From 9c72cbd826528bb64267ba2184ae16099343c7ab Mon Sep 17 00:00:00 2001 From: Adrian Likins Date: Mon, 24 Sep 2007 15:22:16 -0400 Subject: pyflakes cleanups mostly just removing unused modules change "from codes import *" to "import codes" in a couple places and updated accordingly --- modules/func_module.py | 8 ++------ modules/hardware.py | 1 - modules/process.py | 1 - modules/service.py | 5 ++--- modules/smart.py | 1 - modules/test.py | 1 - server/codes.py | 3 --- server/config_data.py | 4 ++-- server/module_loader.py | 3 +-- server/server.py | 1 - 10 files changed, 7 insertions(+), 21 deletions(-) diff --git a/modules/func_module.py b/modules/func_module.py index 7019bc5..a3a8550 100755 --- a/modules/func_module.py +++ b/modules/func_module.py @@ -12,18 +12,14 @@ ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ## -from codes import * from server import config_data from server import logger -import os -import threading -import time -import traceback - class FuncModule(object): + + # the version is meant to version = "0.0.0" api_version = "0.0.0" description = "No Description provided" diff --git a/modules/hardware.py b/modules/hardware.py index 2c41b9f..7c6deb4 100755 --- a/modules/hardware.py +++ b/modules/hardware.py @@ -23,7 +23,6 @@ sys.path.append("/usr/share/smolt/client") import smolt # our modules -from codes import * from modules import func_module # ================================= diff --git a/modules/process.py b/modules/process.py index 3e40fe1..1accbf5 100755 --- a/modules/process.py +++ b/modules/process.py @@ -18,7 +18,6 @@ import sub_process # our modules -from codes import * from modules import func_module # ================================= diff --git a/modules/service.py b/modules/service.py index 524cd7b..433d70b 100755 --- a/modules/service.py +++ b/modules/service.py @@ -14,8 +14,7 @@ ## ## - -from codes import * +import codes from modules import func_module import sub_process @@ -39,7 +38,7 @@ class Service(func_module.FuncModule): if os.path.exists(filename): return sub_process.call(["/sbin/service", service_name, command]) else: - raise FuncException("Service not installed: %s" % service_name) + raise codes.FuncException("Service not installed: %s" % service_name) def start(self, service_name): return self.__command(service_name, "start") diff --git a/modules/smart.py b/modules/smart.py index 4ed8335..0a7be47 100755 --- a/modules/smart.py +++ b/modules/smart.py @@ -19,7 +19,6 @@ import sub_process # our modules -from codes import * from modules import func_module # ================================= diff --git a/modules/test.py b/modules/test.py index ea22007..55265a3 100755 --- a/modules/test.py +++ b/modules/test.py @@ -1,6 +1,5 @@ #!/usr/bin/python -from codes import * from modules import func_module class Test(func_module.FuncModule): diff --git a/server/codes.py b/server/codes.py index dc0ceac..c549709 100755 --- a/server/codes.py +++ b/server/codes.py @@ -14,9 +14,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. """ import exceptions -import string -import sys -import traceback class FuncException(exceptions.Exception): diff --git a/server/config_data.py b/server/config_data.py index 7ace8ca..ed12383 100755 --- a/server/config_data.py +++ b/server/config_data.py @@ -12,8 +12,8 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +import codes -from codes import * import os import ConfigParser @@ -35,7 +35,7 @@ class Config: def read(self): if not os.path.exists(CONFIG_FILE): - raise FuncException("Missing %s" % CONFIG_FILE) + raise codes.FuncException("Missing %s" % CONFIG_FILE) cp = ConfigParser.ConfigParser() diff --git a/server/module_loader.py b/server/module_loader.py index a2a00c5..6fb69f7 100755 --- a/server/module_loader.py +++ b/server/module_loader.py @@ -18,8 +18,7 @@ import distutils.sysconfig import os import sys -import glob -from rhpl.translate import _, N_, textdomain, utf8 +from rhpl.translate import _ def module_walker(topdir): diff --git a/server/server.py b/server/server.py index 73ef114..cd3c9e7 100755 --- a/server/server.py +++ b/server/server.py @@ -17,7 +17,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # standard modules import SimpleXMLRPCServer import string -import socket import sys import traceback -- cgit From 47100aa2f165b47175af1e1aef736c5769a83169 Mon Sep 17 00:00:00 2001 From: Seth Vidal Date: Tue, 25 Sep 2007 11:02:26 -0400 Subject: move files for the new naming scheme --- client/sslclient.py | 44 ------------- minion/AuthedXMLRPCServer.py | 144 +++++++++++++++++++++++++++++++++++++++++++ overlord/sslclient.py | 44 +++++++++++++ server/AuthedXMLRPCServer.py | 144 ------------------------------------------- 4 files changed, 188 insertions(+), 188 deletions(-) delete mode 100644 client/sslclient.py create mode 100644 minion/AuthedXMLRPCServer.py create mode 100644 overlord/sslclient.py delete mode 100644 server/AuthedXMLRPCServer.py diff --git a/client/sslclient.py b/client/sslclient.py deleted file mode 100644 index 9439c4a..0000000 --- a/client/sslclient.py +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/python - -import os -import sys -import xmlrpclib -import urllib - -from func import SSLCommon - - -class SSL_Transport(xmlrpclib.Transport): - - user_agent = "pyOpenSSL_XMLRPC/%s - %s" % ('0.1', xmlrpclib.Transport.user_agent) - - def __init__(self, ssl_context, timeout=None, use_datetime=0): - if sys.version_info[:3] >= (2, 5, 0): - xmlrpclib.Transport.__init__(self, use_datetime) - self.ssl_ctx=ssl_context - self._timeout = timeout - - def make_connection(self, host): - # Handle username and password. - try: - host, extra_headers, x509 = self.get_host_info(host) - except AttributeError: - # Yay for Python 2.2 - pass - _host, _port = urllib.splitport(host) - return SSLCommon.HTTPS(_host, int(_port), ssl_context=self.ssl_ctx, timeout=self._timeout) - - -class SSLXMLRPCServerProxy(xmlrpclib.ServerProxy): - def __init__(self, uri, pkey_file, cert_file, ca_cert_file, timeout=None): - self.ctx = SSLCommon.CreateSSLContext(pkey_file, cert_file, ca_cert_file) - xmlrpclib.ServerProxy.__init__(self, uri, SSL_Transport(ssl_context=self.ctx, timeout=timeout)) - - - -if __name__ == "__main__": - s = SSLXMLRPCServerProxy('https://localhost:51234/', '/etc/pki/func/slave.pem', '/etc/pki/func/slave.crt', '/etc/pki/func/ca/funcmaster.crt') - f = s.ping(1, 2) - print f - - \ No newline at end of file diff --git a/minion/AuthedXMLRPCServer.py b/minion/AuthedXMLRPCServer.py new file mode 100644 index 0000000..490b57a --- /dev/null +++ b/minion/AuthedXMLRPCServer.py @@ -0,0 +1,144 @@ +# 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; either version 2 of the License, or +# (at your option) any later version. +# +# 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# Copyright 2005 Dan Williams and Red Hat, Inc. +# Modifications by Seth Vidal - 2007 + +import os, sys +import socket +import time +import SocketServer +import xmlrpclib +import SimpleXMLRPCServer +from func import SSLCommon +import OpenSSL + + + +class AuthedSimpleXMLRPCRequestHandler(SimpleXMLRPCServer.SimpleXMLRPCRequestHandler): + + # For some reason, httplib closes the connection right after headers + # have been sent if the connection is _not_ HTTP/1.1, which results in + # a "Bad file descriptor" error when the client tries to read from the socket + protocol_version = "HTTP/1.1" + + def setup(self): + """ + We need to use socket._fileobject Because SSL.Connection + doesn't have a 'dup'. Not exactly sure WHY this is, but + this is backed up by comments in socket.py and SSL/connection.c + """ + self.connection = self.request # for doPOST + self.rfile = socket._fileobject(self.request, "rb", self.rbufsize) + self.wfile = socket._fileobject(self.request, "wb", self.wbufsize) + + def do_POST(self): + self.server._this_request = (self.request, self.client_address) + try: + SimpleXMLRPCServer.SimpleXMLRPCRequestHandler.do_POST(self) + except socket.timeout: + pass + except (socket.error, OpenSSL.SSL.SysCallError), e: + print "Error (%s): socket error - '%s'" % (self.client_address, e) + + +class BaseAuthedXMLRPCServer: + def __init__(self, address, authinfo_callback=None): + self.allow_reuse_address = 1 + self.logRequests = 1 + self.authinfo_callback = authinfo_callback + + self.funcs = {} + self.instance = None + + def get_authinfo(self, request, client_address): + print 'down here' + if self.authinfo_callback: + return self.authinfo_callback(request, client_address) + return None + + +class AuthedSSLXMLRPCServer(BaseAuthedXMLRPCServer, SSLCommon.BaseSSLServer, SimpleXMLRPCServer.SimpleXMLRPCServer): + """ Extension to allow more fine-tuned SSL handling """ + + def __init__(self, address, pkey, cert, ca_cert, authinfo_callback=None, timeout=None): + BaseAuthedXMLRPCServer.__init__(self, address, authinfo_callback) + SimpleXMLRPCServer.SimpleXMLRPCServer.__init__(self, address, AuthedSimpleXMLRPCRequestHandler) + SSLCommon.BaseSSLServer.__init__(self, address, AuthedSimpleXMLRPCRequestHandler, pkey, cert, ca_cert, timeout=timeout) + + + +class AuthedXMLRPCServer(BaseAuthedXMLRPCServer, SSLCommon.BaseServer, SimpleXMLRPCServer.SimpleXMLRPCServer): + + def __init__(self, address, authinfo_callback=None): + BaseAuthedXMLRPCServer.__init__(self, address, authinfo_callback) + SSLCommon.BaseServer.__init__(self, address, AuthedSimpleXMLRPCRequestHandler) + + +########################################################### +# Testing stuff +########################################################### + +class ReqHandler: + def ping(self, callerid, trynum): + print 'clearly not' + print callerid + print trynum + return "pong %d / %d" % (callerid, trynum) + +class TestServer(AuthedSSLXMLRPCServer): + """ + SSL XMLRPC server that authenticates clients based on their certificate. + """ + + def __init__(self, address, pkey, cert, ca_cert): + AuthedSSLXMLRPCServer.__init__(self, address, pkey, cert, ca_cert, self.auth_cb) + + def _dispatch(self, method, params): + if method == 'trait_names' or method == '_getAttributeNames': + return dir(self) + # if we have _this_request then we get the peer cert from it + # handling all the authZ checks in _dispatch() means we don't even call the method + # for whatever it wants to do and we have the method name. + + if hasattr(self, '_this_request'): + r,a = self._this_request + p = r.get_peer_certificate() + print dir(p) + print p.get_subject() + else: + print 'no cert' + + return "your mom" + + def auth_cb(self, request, client_address): + peer_cert = request.get_peer_certificate() + return peer_cert.get_subject().CN + + +if __name__ == '__main__': + if len(sys.argv) < 4: + print "Usage: python AuthdXMLRPCServer.py key cert ca_cert" + sys.exit(1) + + pkey = sys.argv[1] + cert = sys.argv[2] + ca_cert = sys.argv[3] + + print "Starting the server." + server = TestServer(('localhost', 51234), pkey, cert, ca_cert) + h = ReqHandler() + server.register_instance(h) + server.serve_forever() + diff --git a/overlord/sslclient.py b/overlord/sslclient.py new file mode 100644 index 0000000..9439c4a --- /dev/null +++ b/overlord/sslclient.py @@ -0,0 +1,44 @@ +#!/usr/bin/python + +import os +import sys +import xmlrpclib +import urllib + +from func import SSLCommon + + +class SSL_Transport(xmlrpclib.Transport): + + user_agent = "pyOpenSSL_XMLRPC/%s - %s" % ('0.1', xmlrpclib.Transport.user_agent) + + def __init__(self, ssl_context, timeout=None, use_datetime=0): + if sys.version_info[:3] >= (2, 5, 0): + xmlrpclib.Transport.__init__(self, use_datetime) + self.ssl_ctx=ssl_context + self._timeout = timeout + + def make_connection(self, host): + # Handle username and password. + try: + host, extra_headers, x509 = self.get_host_info(host) + except AttributeError: + # Yay for Python 2.2 + pass + _host, _port = urllib.splitport(host) + return SSLCommon.HTTPS(_host, int(_port), ssl_context=self.ssl_ctx, timeout=self._timeout) + + +class SSLXMLRPCServerProxy(xmlrpclib.ServerProxy): + def __init__(self, uri, pkey_file, cert_file, ca_cert_file, timeout=None): + self.ctx = SSLCommon.CreateSSLContext(pkey_file, cert_file, ca_cert_file) + xmlrpclib.ServerProxy.__init__(self, uri, SSL_Transport(ssl_context=self.ctx, timeout=timeout)) + + + +if __name__ == "__main__": + s = SSLXMLRPCServerProxy('https://localhost:51234/', '/etc/pki/func/slave.pem', '/etc/pki/func/slave.crt', '/etc/pki/func/ca/funcmaster.crt') + f = s.ping(1, 2) + print f + + \ No newline at end of file diff --git a/server/AuthedXMLRPCServer.py b/server/AuthedXMLRPCServer.py deleted file mode 100644 index 490b57a..0000000 --- a/server/AuthedXMLRPCServer.py +++ /dev/null @@ -1,144 +0,0 @@ -# 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; either version 2 of the License, or -# (at your option) any later version. -# -# 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# Copyright 2005 Dan Williams and Red Hat, Inc. -# Modifications by Seth Vidal - 2007 - -import os, sys -import socket -import time -import SocketServer -import xmlrpclib -import SimpleXMLRPCServer -from func import SSLCommon -import OpenSSL - - - -class AuthedSimpleXMLRPCRequestHandler(SimpleXMLRPCServer.SimpleXMLRPCRequestHandler): - - # For some reason, httplib closes the connection right after headers - # have been sent if the connection is _not_ HTTP/1.1, which results in - # a "Bad file descriptor" error when the client tries to read from the socket - protocol_version = "HTTP/1.1" - - def setup(self): - """ - We need to use socket._fileobject Because SSL.Connection - doesn't have a 'dup'. Not exactly sure WHY this is, but - this is backed up by comments in socket.py and SSL/connection.c - """ - self.connection = self.request # for doPOST - self.rfile = socket._fileobject(self.request, "rb", self.rbufsize) - self.wfile = socket._fileobject(self.request, "wb", self.wbufsize) - - def do_POST(self): - self.server._this_request = (self.request, self.client_address) - try: - SimpleXMLRPCServer.SimpleXMLRPCRequestHandler.do_POST(self) - except socket.timeout: - pass - except (socket.error, OpenSSL.SSL.SysCallError), e: - print "Error (%s): socket error - '%s'" % (self.client_address, e) - - -class BaseAuthedXMLRPCServer: - def __init__(self, address, authinfo_callback=None): - self.allow_reuse_address = 1 - self.logRequests = 1 - self.authinfo_callback = authinfo_callback - - self.funcs = {} - self.instance = None - - def get_authinfo(self, request, client_address): - print 'down here' - if self.authinfo_callback: - return self.authinfo_callback(request, client_address) - return None - - -class AuthedSSLXMLRPCServer(BaseAuthedXMLRPCServer, SSLCommon.BaseSSLServer, SimpleXMLRPCServer.SimpleXMLRPCServer): - """ Extension to allow more fine-tuned SSL handling """ - - def __init__(self, address, pkey, cert, ca_cert, authinfo_callback=None, timeout=None): - BaseAuthedXMLRPCServer.__init__(self, address, authinfo_callback) - SimpleXMLRPCServer.SimpleXMLRPCServer.__init__(self, address, AuthedSimpleXMLRPCRequestHandler) - SSLCommon.BaseSSLServer.__init__(self, address, AuthedSimpleXMLRPCRequestHandler, pkey, cert, ca_cert, timeout=timeout) - - - -class AuthedXMLRPCServer(BaseAuthedXMLRPCServer, SSLCommon.BaseServer, SimpleXMLRPCServer.SimpleXMLRPCServer): - - def __init__(self, address, authinfo_callback=None): - BaseAuthedXMLRPCServer.__init__(self, address, authinfo_callback) - SSLCommon.BaseServer.__init__(self, address, AuthedSimpleXMLRPCRequestHandler) - - -########################################################### -# Testing stuff -########################################################### - -class ReqHandler: - def ping(self, callerid, trynum): - print 'clearly not' - print callerid - print trynum - return "pong %d / %d" % (callerid, trynum) - -class TestServer(AuthedSSLXMLRPCServer): - """ - SSL XMLRPC server that authenticates clients based on their certificate. - """ - - def __init__(self, address, pkey, cert, ca_cert): - AuthedSSLXMLRPCServer.__init__(self, address, pkey, cert, ca_cert, self.auth_cb) - - def _dispatch(self, method, params): - if method == 'trait_names' or method == '_getAttributeNames': - return dir(self) - # if we have _this_request then we get the peer cert from it - # handling all the authZ checks in _dispatch() means we don't even call the method - # for whatever it wants to do and we have the method name. - - if hasattr(self, '_this_request'): - r,a = self._this_request - p = r.get_peer_certificate() - print dir(p) - print p.get_subject() - else: - print 'no cert' - - return "your mom" - - def auth_cb(self, request, client_address): - peer_cert = request.get_peer_certificate() - return peer_cert.get_subject().CN - - -if __name__ == '__main__': - if len(sys.argv) < 4: - print "Usage: python AuthdXMLRPCServer.py key cert ca_cert" - sys.exit(1) - - pkey = sys.argv[1] - cert = sys.argv[2] - ca_cert = sys.argv[3] - - print "Starting the server." - server = TestServer(('localhost', 51234), pkey, cert, ca_cert) - h = ReqHandler() - server.register_instance(h) - server.serve_forever() - -- cgit From 91908a6228316dadf22de4eca88354bd59807fc3 Mon Sep 17 00:00:00 2001 From: Adrian Likins Date: Tue, 25 Sep 2007 12:35:49 -0400 Subject: couple of utility makefiles mainly just so I can type "make clean" before "git status" but also includes targets for pychecker and pyflakes --- minion/Makefile | 19 +++++++++++++++++++ modules/Makefile | 19 +++++++++++++++++++ overlord/Makefile | 19 +++++++++++++++++++ 3 files changed, 57 insertions(+) create mode 100755 minion/Makefile create mode 100755 modules/Makefile create mode 100755 overlord/Makefile diff --git a/minion/Makefile b/minion/Makefile new file mode 100755 index 0000000..86a3db8 --- /dev/null +++ b/minion/Makefile @@ -0,0 +1,19 @@ + + +PYFILES = $(wildcard *.py) + +PYCHECKER = /usr/bin/pychecker +PYFLAKES = /usr/bin/pyflakes + +clean:: + @rm -fv *.pyc *~ .*~ *.pyo + @find . -name .\#\* -exec rm -fv {} \; + @rm -fv *.rpm + + +pychecker:: + @$(PYCHECKER) $(PYFILES) || exit 0 + +pyflakes:: + @$(PYFLAKES) $(PYFILES) || exit 0 + diff --git a/modules/Makefile b/modules/Makefile new file mode 100755 index 0000000..86a3db8 --- /dev/null +++ b/modules/Makefile @@ -0,0 +1,19 @@ + + +PYFILES = $(wildcard *.py) + +PYCHECKER = /usr/bin/pychecker +PYFLAKES = /usr/bin/pyflakes + +clean:: + @rm -fv *.pyc *~ .*~ *.pyo + @find . -name .\#\* -exec rm -fv {} \; + @rm -fv *.rpm + + +pychecker:: + @$(PYCHECKER) $(PYFILES) || exit 0 + +pyflakes:: + @$(PYFLAKES) $(PYFILES) || exit 0 + diff --git a/overlord/Makefile b/overlord/Makefile new file mode 100755 index 0000000..86a3db8 --- /dev/null +++ b/overlord/Makefile @@ -0,0 +1,19 @@ + + +PYFILES = $(wildcard *.py) + +PYCHECKER = /usr/bin/pychecker +PYFLAKES = /usr/bin/pyflakes + +clean:: + @rm -fv *.pyc *~ .*~ *.pyo + @find . -name .\#\* -exec rm -fv {} \; + @rm -fv *.rpm + + +pychecker:: + @$(PYCHECKER) $(PYFILES) || exit 0 + +pyflakes:: + @$(PYFLAKES) $(PYFILES) || exit 0 + -- cgit From 50c32af5a366bfd5c3a74c468ed47f97684372ab Mon Sep 17 00:00:00 2001 From: Adrian Likins Date: Tue, 25 Sep 2007 13:07:54 -0400 Subject: Be a bit more paranoid about sub processes. Before we could just send "aux; some_arbitrary_command_here" and "some_arbitrary_command_here" would get executed. Also, for some reason, if we send process.kill just one argument, it kills funcd dead. I'm not sure why currently --- modules/process.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/modules/process.py b/modules/process.py index 1accbf5..2c40f9b 100755 --- a/modules/process.py +++ b/modules/process.py @@ -40,7 +40,9 @@ class ProcessModule(func_module.FuncModule): flags.replace(";","") # prevent stupidity - cmd = sub_process.Popen("ps %s" % flags,stdout=sub_process.PIPE,shell=True) + + #FIXME: we need to swallow stdout/stderr as well, right now it spews to the console + cmd = sub_process.Popen(["/bin/ps", flags] ,executable="/bin/ps", stdout=sub_process.PIPE,shell=False) data = cmd.communicate()[0] results = [] @@ -51,13 +53,14 @@ class ProcessModule(func_module.FuncModule): return results + def kill(self,pid,level=""): - rc = sub_process.call("/bin/kill %s %s" % (pid, level), shell=True) + rc = sub_process.call(["/bin/kill", pid, level], executable="/bin/kill", shell=False) return rc def pkill(self,name,level=""): # example killall("thunderbird","-9") - rc = sub_process.call("/usr/bin/pkill %s %s" % (name, level), shell=True) + rc = sub_process.call(["/usr/bin/pkill", name, level], executable="/usr/bin/pkill", shell=False) return rc methods = ProcessModule() -- cgit From 35c3766557793329b9e1ea31b18ea66830367845 Mon Sep 17 00:00:00 2001 From: Adrian Likins Date: Tue, 25 Sep 2007 13:40:56 -0400 Subject: fix up logging a bit. I was sending the audit logs and the svc logs to the same logger before --- minion/logger.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/minion/logger.py b/minion/logger.py index 1e60dc0..7747824 100755 --- a/minion/logger.py +++ b/minion/logger.py @@ -55,7 +55,8 @@ class Logger(Singleton): self._no_handlers = False -class AuditLogger(Logger): +class AuditLogger(Singleton): + _no_handlers = True def __init__(self, logfilepath = "/var/log/func/audit.log"): self.loglevel = logging.INFO self._setup_logging() @@ -67,6 +68,16 @@ class AuditLogger(Logger): self.logger.info("%s called with %s" % (method, params)) + def _setup_logging(self): + self.logger = logging.getLogger("audit") + + def _setup_handlers(self, logfilepath="/var/log/func/audit.log"): + handler = logging.FileHandler(logfilepath, "a") + self.logger.setLevel(self.loglevel) + formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s") + handler.setFormatter(formatter) + self.logger.addHandler(handler) + self._no_handlers = False -- cgit From 6d5746d617385978fb316ac90cc05eaa0f39b8b9 Mon Sep 17 00:00:00 2001 From: Adrian Likins Date: Tue, 25 Sep 2007 14:20:17 -0400 Subject: catch some potentially bad args to the process.kill method We don't want empty args to end up killing the calling process, aka, funcd, so we filter those out. --- modules/process.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/modules/process.py b/modules/process.py index 2c40f9b..78e5aea 100755 --- a/modules/process.py +++ b/modules/process.py @@ -16,6 +16,7 @@ # other modules import sub_process +import codes # our modules from modules import func_module @@ -54,8 +55,16 @@ class ProcessModule(func_module.FuncModule): return results - def kill(self,pid,level=""): - rc = sub_process.call(["/bin/kill", pid, level], executable="/bin/kill", shell=False) + def kill(self,pid,signal="TERM"): + if pid == "0": + raise codes.FuncException("Killing pid group 0 not permitted") + if signal == "": + # this is default /bin/kill behaviour, it claims, but enfore it anyway + signal = "-TERM" + if signal[0] != "-": + signal = "-%s" % signal + rc = sub_process.call(["/bin/kill",signal, pid], executable="/bin/kill", shell=False) + print rc return rc def pkill(self,name,level=""): -- cgit From 3675cf7df32d59000a45c2b2932ec8a19a0d1c9d Mon Sep 17 00:00:00 2001 From: Seth Vidal Date: Tue, 25 Sep 2007 14:38:38 -0400 Subject: clean up configs in certmaster.py make certmaster script work --- func/certmaster.py | 41 +++++++++++++++++++---------------------- scripts/certmaster | 13 +++++++++++-- 2 files changed, 30 insertions(+), 24 deletions(-) diff --git a/func/certmaster.py b/func/certmaster.py index 02c8013..bd01db9 100755 --- a/func/certmaster.py +++ b/func/certmaster.py @@ -34,7 +34,7 @@ class SimpleConfigFile(object): """simple config file object: reads in key=value pairs from a file and stores each as an attribute""" - def __init__(self, filename): + def __init__(self, filename, defaults={}): self.fn = filename fo = open(filename, 'r') for line in fo.readlines(): @@ -44,34 +44,31 @@ class SimpleConfigFile(object): key = key.strip().lower() val = val.strip() setattr(self, key, val) + for k,v in defaults.items(): + if not hasattr(self, k): + setattr(self, k, v) fo.close() class CertMaster(object): - def __init__(self, conf_file): - self.cfg = SimpleConfigFile(conf_file) - self.listen_addr = 'localhost' - self.listen_port = '51235' - self.cadir = '/etc/pki/func/ca' - self.certroot = '/etc/pki/func/ca/certs' - self.csrroot = '/etc/pki/func/ca/csrs' - self.autosign = True - for attr in ['listen_addr', 'listen_port', 'cadir', 'certroot', - 'csrroot']: - if hasattr(self.cfg, attr): - setattr(self, attr, getattr(self.cfg, attr)) + def __init__(self, conf_file, defaults={}): + self.cfg = SimpleConfigFile(conf_file, defaults) if hasattr(self.cfg, 'autosign'): if getattr(self.cfg, 'autosign').lower() in ['yes', 'true', 1, 'on']: - self.autosign = True + self.cfg.autosign = True elif getattr(self.cfg, 'autosign').lower() in ['no', 'false', 0, 'off']: - self.autosign = False + self.cfg.autosign = False + else: + self.cfg.autosign = False + self.cfg.listen_port = int(self.cfg.listen_port) + # open up the cakey and cacert so we have them available - ca_key_file = '%s/funcmaster.key' % self.cadir - ca_cert_file = '%s/funcmaster.crt' % self.cadir + ca_key_file = '%s/funcmaster.key' % self.cfg.cadir + ca_cert_file = '%s/funcmaster.crt' % self.cfg.cadir self.cakey = func.certs.retrieve_key_from_file(ca_key_file) self.cacert = func.certs.retrieve_cert_from_file(ca_cert_file) - for dirpath in [self.cadir, self.certroot, self.csrroot]: + for dirpath in [self.cfg.cadir, self.cfg.certroot, self.cfg.csrroot]: if not os.path.exists(dirpath): os.makedirs(dirpath) @@ -105,8 +102,8 @@ class CertMaster(object): return False, '', '' requesting_host = csrreq.get_subject().CN - certfile = '%s/%s.pem' % (self.certroot, requesting_host) - csrfile = '%s/%s.csr' % (self.csrroot, requesting_host) + certfile = '%s/%s.pem' % (self.cfg.certroot, requesting_host) + csrfile = '%s/%s.csr' % (self.cfg.csrroot, requesting_host) # check for old csr on disk # if we have it - compare the two - if they are not the same - raise a fault @@ -138,7 +135,7 @@ class CertMaster(object): if self.autosign: slavecert = func.certs.create_slave_certificate(csrreq, - self.cakey, self.cacert, self.cadir) + self.cakey, self.cacert, self.cfg.cadir) destfo = open(certfile, 'w') destfo.write(crypto.dump_certificate(crypto.FILETYPE_PEM, slavecert)) @@ -165,7 +162,7 @@ def serve(xmlrpcinstance): Code for starting the XMLRPC service. """ - server =FuncXMLRPCServer((xmlrpcinstance.listen_addr, xmlrpcinstance.list_port)) + server = SimpleXMLRPCServer.SimpleXMLRPCServer((xmlrpcinstance.cfg.listen_addr, xmlrpcinstance.cfg.listen_port)) server.logRequests = 0 # don't print stuff to console server.register_instance(xmlrpcinstance) server.serve_forever() diff --git a/scripts/certmaster b/scripts/certmaster index 3b212b4..1be4c58 100755 --- a/scripts/certmaster +++ b/scripts/certmaster @@ -7,6 +7,15 @@ sys.path.append("%s/func" % distutils.sysconfig.get_python_lib()) import certmaster -cm = certmaster.CertMaster('/etc/func/certmaster.conf') -server = certmaster.serve(cm) +defaults = { 'listen_addr': 'localhost', + 'listen_port': '51235', + 'cadir': '/etc/pki/func/ca', + 'certroot': '/var/lib/func/certmaster/certs', + 'csrroot': '/var/lib/func/certmaster/csrs', + 'autosign': 'false' + } + +cm = certmaster.CertMaster('/etc/func/certmaster.conf', defaults) +certmaster.serve(cm) + -- cgit