=== modified file 'Makefile' --- Makefile 2008-08-08 02:33:41 +0000 +++ Makefile 2008-08-08 23:28:55 +0000 @@ -21,14 +21,13 @@ all: $(PROGS) $(DOCS) %.5: %.xml - $(DOCBOOKTOMAN) $^ + cd $(shell dirname $^); $(DOCBOOKTOMAN) $(shell basename $^) %.8: %.xml - $(DOCBOOKTOMAN) $^ + cd $(shell dirname $^); $(DOCBOOKTOMAN) $(shell basename $^) %.8mandos: %.xml - $(DOCBOOKTOMAN) $^ - -mv ./$(shell basename $@) $@ 2>/dev/null + cd $(shell dirname $^); $(DOCBOOKTOMAN) $(shell basename $^) mandos-client: mandos-client.o $(LINK.o) -lgnutls $(COMMON) $^ $(LOADLIBES) $(LDLIBS) -o $@ === modified file 'TODO' --- TODO 2008-08-09 04:42:39 +0000 +++ TODO 2008-08-09 04:49:12 +0000 @@ -30,9 +30,7 @@ ** [#A] Command man page: man8/mandos.8 ** [#A] Config file man page: man5/mandos.conf (mandos.conf) ** [#A] Config file man page: man5/mandos-clients.conf (clients.conf) -** [#A] write PID file ** [#A] /etc/init.d/mandos-server -** Better comments in config files ** Log level ** /etc/mandos/clients.d/*.conf Watch this directory and add/remove/update clients? @@ -53,6 +51,8 @@ * Installer ** [#A] Change initrd.img file to not be publically readable ** [#A] Create GPG key ring files in initrd +** [#A] Create mandos user and group for server +** [#A] Create /var/run/mandos directory with perm and ownership #+STARTUP: showall === modified file 'clients.conf' --- clients.conf 2008-08-08 01:51:58 +0000 +++ clients.conf 2008-08-09 01:39:09 +0000 @@ -1,35 +1,66 @@ +# Default settings for all clients. These values are the default +# values, so uncomment and change them if you want different ones. [DEFAULT] -timeout = 1h -interval = 5m -checker = fping -q -- %%(fqdn)s - -# Example -[foo] -fingerprint = 3e393aeaefb84c7e89e2f547b3a107558fca3a27 -secret = Base+64+encoded+OpenPGP+encrypted+data/= -# secfile = /etc/mandos/foo-secret.txt.asc -fqdn = foo.example.org -checker = fping -q -- %%(fqdn)s -timeout = 10m - -[braxen_client] -fingerprint = 7788 2722 5BA7 DE53 9C5A 7CFA 59CF F7CD BD9A 5920 -secret = - hQIOA6QdEjBs2L/HEAf/TCyrDe5Xnm9esa+Pb/vWF9CUqfn4srzVgSu234 - REJMVv7lBSrPE2132Lmd2gqF1HeLKDJRSVxJpt6xoWOChGHg+TMyXDxK+N - Xl89vGvdU1XfhKkVm9MDLOgT5ECDPysDGHFPDhqHOSu3Kaw2DWMV/iH9vz - 3Z20erVNbdcvyBnuojcoWO/6yfB5EQO0BXp7kcyy00USA3CjD5FGZdoQGI - Tb8A/ar0tVA5crSQmaSotm6KmNLhrFnZ5BxX+TiE+eTUTqSloWRY6VAvqW - QHC7OASxK5E6RXPBuFH5IohUA2Qbk5AHt99pYvsIPX88j2rWauOokoiKZo - t/9leJ8VxO5l3wf/U64IH8bkPIoWmWZfd/nqh4uwGNbCgKMyT+AnvH7kMJ - 3i7DivfWl2mKLV0PyPHUNva0VQxX6yYjcOhj1R6fCr/at8/NSLe2OhLchz - dC+Ls9h+kvJXgF8Sisv+Wk/1RadPLFmraRlqvJwt6Ww21LpiXqXHV2mIgq - WnR98YgSvUi3TJHrUQiNc9YyBzuRo0AjgG2C9qiE3FM+Y28+iQ/sR3+bFs - zYuZKVTObqiIslwXu7imO0cvvFRgJF/6u3HNFQ4LUTGhiM3FQmC6NNlF3/ - vJM2hwRDMcJqDd54Twx90Wh+tYz0z7QMsK4ANXWHHWHR0JchnLWmenzbtW - 5MHdW9AYsNJZAQSOpirE4Xi31CSlWAi9KV+cUCmWF5zOFy1x23P6PjdaRm - 4T2zw4dxS5NswXWU0sVEXxjs6PYxuIiCTL7vdpx8QjBkrPWDrAbcMyBr2O - QlnHIvPzEArRQLo= - =iHhv -fqdn = localhost -interval = 5m + +# How long until a client is considered invalid - that is, ineligible +# to get the data this server holds. +;timeout = 1h + +# How often to run the checker to confirm that a client is still up. +# Note: a new checker will not be started if an old one is still +# running. The server will wait for a checker to complete until the +# "timeout" above occurs, at which time the client will be marked +# invalid, and any running checker killed. +;interval = 5m + +# What command to run as "the checker". +;checker = fping -q -- %%(host)s + + +;#### +;# Example client named "foo" +;[foo] +; +;# OpenPGP key fingerprint for "foo" +;fingerprint = 7788 2722 5BA7 DE53 9C5A 7CFA 59CF F7CD BD9A 5920 +; +;# This is base64-encoded binary data. It will be decoded and sent to +;# the client matching the above fingerprint. This should, of course, +;# be OpenPGP encrypted data, decryptable only by the client. +;secret = +; hQIOA6QdEjBs2L/HEAf/TCyrDe5Xnm9esa+Pb/vWF9CUqfn4srzVgSu234 +; REJMVv7lBSrPE2132Lmd2gqF1HeLKDJRSVxJpt6xoWOChGHg+TMyXDxK+N +; Xl89vGvdU1XfhKkVm9MDLOgT5ECDPysDGHFPDhqHOSu3Kaw2DWMV/iH9vz +; 3Z20erVNbdcvyBnuojcoWO/6yfB5EQO0BXp7kcyy00USA3CjD5FGZdoQGI +; Tb8A/ar0tVA5crSQmaSotm6KmNLhrFnZ5BxX+TiE+eTUTqSloWRY6VAvqW +; QHC7OASxK5E6RXPBuFH5IohUA2Qbk5AHt99pYvsIPX88j2rWauOokoiKZo +; t/9leJ8VxO5l3wf/U64IH8bkPIoWmWZfd/nqh4uwGNbCgKMyT+AnvH7kMJ +; 3i7DivfWl2mKLV0PyPHUNva0VQxX6yYjcOhj1R6fCr/at8/NSLe2OhLchz +; dC+Ls9h+kvJXgF8Sisv+Wk/1RadPLFmraRlqvJwt6Ww21LpiXqXHV2mIgq +; WnR98YgSvUi3TJHrUQiNc9YyBzuRo0AjgG2C9qiE3FM+Y28+iQ/sR3+bFs +; zYuZKVTObqiIslwXu7imO0cvvFRgJF/6u3HNFQ4LUTGhiM3FQmC6NNlF3/ +; vJM2hwRDMcJqDd54Twx90Wh+tYz0z7QMsK4ANXWHHWHR0JchnLWmenzbtW +; 5MHdW9AYsNJZAQSOpirE4Xi31CSlWAi9KV+cUCmWF5zOFy1x23P6PjdaRm +; 4T2zw4dxS5NswXWU0sVEXxjs6PYxuIiCTL7vdpx8QjBkrPWDrAbcMyBr2O +; QlnHIvPzEArRQLo= +; =iHhv +; +;# Host name; used only by the checker, not used by the server itself. +;host = foo.example.org +;#### + +;#### +;# Another example client, named "bar". +;[bar] +;# The fingerprint is not space or case sensitive +;fingerprint = 3e393aeaefb84c7e89e2f547b3a107558fca3a27 +; +;# If "secret" is not specified, a file can be read for the data. +;;secfile = /etc/mandos/bar-secret.txt.asc +; +;# An IP address for host is also fine, if the checker accepts it. +;host = 192.0.2.3 +; +;# Parameters from the [DEFAULT] section can be overridden per client. +;interval = 5m +;#### === modified file 'mandos' --- mandos 2008-08-08 01:17:17 +0000 +++ mandos 2008-08-09 02:53:48 +0000 @@ -64,11 +64,11 @@ logger = logging.Logger('mandos') syslogger = logging.handlers.SysLogHandler\ - (facility = logging.handlers.SysLogHandler.LOG_DAEMON) + (facility = logging.handlers.SysLogHandler.LOG_DAEMON, + address = "/dev/log") syslogger.setFormatter(logging.Formatter\ - ('%(levelname)s: %(message)s')) + ('Mandos: %(levelname)s: %(message)s')) logger.addHandler(syslogger) -del syslogger class AvahiError(Exception): @@ -102,7 +102,7 @@ """ def __init__(self, interface = avahi.IF_UNSPEC, name = None, type = None, port = None, TXT = None, domain = "", - host = "", max_renames = 12): + host = "", max_renames = 32768): self.interface = interface self.name = name self.type = type @@ -122,6 +122,9 @@ raise AvahiServiceError("Too many renames") name = server.GetAlternativeServiceName(name) logger.error(u"Changing name to %r ...", name) + syslogger.setFormatter(logging.Formatter\ + ('Mandos (%s): %%(levelname)s:' + ' %%(message)s' % name)) self.remove() self.add() self.rename_count += 1 @@ -163,7 +166,7 @@ fingerprint: string (40 or 32 hexadecimal digits); used to uniquely identify the client secret: bytestring; sent verbatim (over TLS) to client - fqdn: string (FQDN); available for use by the checker command + host: string; available for use by the checker command created: datetime.datetime(); object creation, not client host last_checked_ok: datetime.datetime() or None if not yet checked OK timeout: datetime.timedelta(); How long from last_checked_ok @@ -230,7 +233,7 @@ else: raise TypeError(u"No secret or secfile for client %s" % self.name) - self.fqdn = config.get("fqdn", "") + self.host = config.get("host", "") self.created = datetime.datetime.now() self.last_checked_ok = None self.timeout = string_to_delta(config["timeout"]) @@ -259,7 +262,7 @@ The possibility that a client might be restarted is left open, but not currently used.""" # If this client doesn't have a secret, it is already stopped. - if self.secret: + if hasattr(self, "secret") and self.secret: logger.info(u"Stopping client %s", self.name) self.secret = None else: @@ -313,7 +316,7 @@ if self.checker is None: try: # In case check_command has exactly one % operator - command = self.check_command % self.fqdn + command = self.check_command % self.host except TypeError: # Escape attributes for the shell escaped_attrs = dict((key, re.escape(str(val))) @@ -346,7 +349,7 @@ self.checker_callback_tag = None if getattr(self, "checker", None) is None: return - logger.debug("Stopping checker for %(name)s", vars(self)) + logger.debug(u"Stopping checker for %(name)s", vars(self)) try: os.kill(self.checker.pid, signal.SIGTERM) #os.sleep(0.5) @@ -709,10 +712,21 @@ del options # Now we have our good server settings in "server_settings" + debug = server_settings["debug"] + + if not debug: + syslogger.setLevel(logging.WARNING) + + if server_settings["servicename"] != "Mandos": + syslogger.setFormatter(logging.Formatter\ + ('Mandos (%s): %%(levelname)s:' + ' %%(message)s' + % server_settings["servicename"])) + # Parse config file with clients client_defaults = { "timeout": "1h", "interval": "5m", - "checker": "fping -q -- %%(fqdn)s", + "checker": "fping -q -- %%(host)s", } client_config = ConfigParser.SafeConfigParser(client_defaults) client_config.read(os.path.join(server_settings["configdir"], @@ -736,8 +750,6 @@ avahi.DBUS_INTERFACE_SERVER ) # End of Avahi example code - debug = server_settings["debug"] - if debug: console = logging.StreamHandler() # console.setLevel(logging.DEBUG) @@ -758,10 +770,24 @@ config = dict(client_config.items(section))) for section in client_config.sections())) + if not clients: + logger.critical(u"No clients defined") + sys.exit(1) if not debug: daemon() + pidfilename = "/var/run/mandos/mandos.pid" + pid = os.getpid() + try: + pidfile = open(pidfilename, "w") + pidfile.write(str(pid) + "\n") + pidfile.close() + del pidfile + except IOError, err: + logger.error(u"Could not write %s file with PID %d", + pidfilename, os.getpid()) + def cleanup(): "Cleanup function; run on exit" global group @@ -813,7 +839,7 @@ tcp_server.handle_request\ (*args[2:], **kwargs) or True) - logger.debug("Starting main loop") + logger.debug(u"Starting main loop") main_loop_started = True main_loop.run() except AvahiError, error: === modified file 'mandos-clients.conf.xml' --- mandos-clients.conf.xml 2008-08-08 02:33:41 +0000 +++ mandos-clients.conf.xml 2008-08-09 01:39:09 +0000 @@ -126,7 +126,7 @@ This option allows you to override the default shell command that the server will use to check up if the client - is still up. By default mandos will "fping -q -- %%(fqdn)s" + is still up. By default mandos will "fping -q -- %%(host)s" @@ -174,10 +174,10 @@ - fqdn + host - FQDN, that can be used in for checking that the client is up. + Host name that can be used in for checking that the client is up. @@ -212,7 +212,7 @@ [DEFAULT] timeout = 1h interval = 5m -checker = fping -q -- %%(fqdn)s +checker = fping -q -- %%(host)s [example_client] fingerprint = 7788 2722 5BA7 DE53 9C5A 7CFA 59CF F7CD BD9A 5920 @@ -235,7 +235,7 @@ QlnHIvPzEArRQLo= =iHhv -fqdn = localhost +host = localhost interval = 5m === modified file 'mandos.conf' --- mandos.conf 2008-08-08 01:17:17 +0000 +++ mandos.conf 2008-08-09 01:39:09 +0000 @@ -1,7 +1,38 @@ +# This file must have exactly one section named "server". [server] -#interface = -#address = -#port = -#debug = False -#priority = SECURE256:!CTYPE-X.509:+CTYPE-OPENPGP -#servicename = Mandos + +# These are the default values for the server, uncomment and change +# them if needed. + + +# If "interface" is set, the server will only listen to a specific +# network interface. +;interface = + + +# If "address" is set, the server will only listen to a specific +# address. This must currently be an IPv6 address; an IPv4 address +# can be specified using the "::FFFF:192.0.2.3" syntax. Also, if this +# is a link-local address, an interface should be set above. +;address = + + +# If "port" is set, the server to bind to that port. By default, the +# server will listen to an arbitrary port. +;port = + + +# If "debug" is true, the server will run in the foreground and print +# a lot of debugging information. +;debug = False + + +# GnuTLS priority for the TLS handshake. See gnutls_priority_init(3). +;priority = SECURE256:!CTYPE-X.509:+CTYPE-OPENPGP + + +# Zeroconf service name. You need to change this if you for some +# reason want to run more than one server on the same *host*. +# If there are name collisions on the same *network*, the server will +# rename itself to "Mandos #2", etc. +;servicename = Mandos