=== modified file 'mandos-ctl'
--- mandos-ctl 2016-06-28 18:52:00 +0000
+++ mandos-ctl 2016-08-25 16:17:23 +0000
@@ -1,11 +1,11 @@
#!/usr/bin/python
# -*- mode: python; coding: utf-8 -*-
-#
+#
# Mandos Monitor - Control and monitor the Mandos server
-#
+#
# Copyright © 2008-2016 Teddy Hogeborn
# Copyright © 2008-2016 Björn Påhlsson
-#
+#
# 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 3 of the License, or
@@ -15,13 +15,13 @@
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
-#
+#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see
# .
-#
+#
# Contact the authors at .
-#
+#
from __future__ import (division, absolute_import, print_function,
unicode_literals)
@@ -83,18 +83,19 @@
except AttributeError:
dbus.OBJECT_MANAGER_IFACE = "org.freedesktop.DBus.ObjectManager"
+
def milliseconds_to_string(ms):
td = datetime.timedelta(0, 0, 0, ms)
- return ("{days}{hours:02}:{minutes:02}:{seconds:02}".format(
- days = "{}T".format(td.days) if td.days else "",
- hours = td.seconds // 3600,
- minutes = (td.seconds % 3600) // 60,
- seconds = td.seconds % 60))
+ return ("{days}{hours:02}:{minutes:02}:{seconds:02}"
+ .format(days="{}T".format(td.days) if td.days else "",
+ hours=td.seconds // 3600,
+ minutes=(td.seconds % 3600) // 60,
+ seconds=td.seconds % 60))
def rfc3339_duration_to_delta(duration):
"""Parse an RFC 3339 "duration" and return a datetime.timedelta
-
+
>>> rfc3339_duration_to_delta("P7D")
datetime.timedelta(7)
>>> rfc3339_duration_to_delta("PT60S")
@@ -110,14 +111,14 @@
>>> rfc3339_duration_to_delta("P1DT3M20S")
datetime.timedelta(1, 200)
"""
-
+
# Parsing an RFC 3339 duration with regular expressions is not
# possible - there would have to be multiple places for the same
# values, like seconds. The current code, while more esoteric, is
# cleaner without depending on a parsing library. If Python had a
# built-in library for parsing we would use it, but we'd like to
# avoid excessive use of external libraries.
-
+
# New type for defining tokens, syntax, and semantics all-in-one
Token = collections.namedtuple("Token", (
"regexp", # To match token; if "value" is not None, must have
@@ -156,11 +157,14 @@
frozenset((token_year, token_month,
token_day, token_time,
token_week)))
- # Define starting values
- value = datetime.timedelta() # Value so far
+ # Define starting values:
+ # Value so far
+ value = datetime.timedelta()
found_token = None
- followers = frozenset((token_duration, )) # Following valid tokens
- s = duration # String left to parse
+ # Following valid tokens
+ followers = frozenset((token_duration, ))
+ # String left to parse
+ s = duration
# Loop until end token is found
while found_token is not token_end:
# Search for any currently valid tokens
@@ -190,7 +194,7 @@
def string_to_delta(interval):
"""Parse a string and return a datetime.timedelta
-
+
>>> string_to_delta('7d')
datetime.timedelta(7)
>>> string_to_delta('60s')
@@ -204,15 +208,15 @@
>>> string_to_delta('5m 30s')
datetime.timedelta(0, 330)
"""
-
+
try:
return rfc3339_duration_to_delta(interval)
except ValueError:
pass
-
+
value = datetime.timedelta(0)
regexp = re.compile(r"(\d+)([dsmhw]?)")
-
+
for num, suffix in regexp.findall(interval):
if suffix == "d":
value += datetime.timedelta(int(num))
@@ -237,20 +241,20 @@
"ApprovalDuration", "ExtendedTimeout"):
return milliseconds_to_string(value)
return str(value)
-
+
# Create format string to print table rows
format_string = " ".join("{{{key}:{width}}}".format(
- width = max(len(tablewords[key]),
- max(len(valuetostring(client[key], key))
- for client in clients)),
- key = key)
+ width=max(len(tablewords[key]),
+ max(len(valuetostring(client[key], key))
+ for client in clients)),
+ key=key)
for key in keywords)
# Print header line
print(format_string.format(**tablewords))
for client in clients:
- print(format_string.format(**{
- key: valuetostring(client[key], key)
- for key in keywords }))
+ print(format_string
+ .format(**{key: valuetostring(client[key], key)
+ for key in keywords}))
def has_actions(options):
@@ -277,7 +281,7 @@
def main():
parser = argparse.ArgumentParser()
parser.add_argument("--version", action="version",
- version = "%(prog)s {}".format(version),
+ version="%(prog)s {}".format(version),
help="show version number and exit")
parser.add_argument("-a", "--all", action="store_true",
help="Select all clients")
@@ -329,59 +333,61 @@
help="Run self-test")
parser.add_argument("client", nargs="*", help="Client name")
options = parser.parse_args()
-
+
if has_actions(options) and not (options.client or options.all):
parser.error("Options require clients names or --all.")
if options.verbose and has_actions(options):
parser.error("--verbose can only be used alone.")
- if options.dump_json and (options.verbose or has_actions(options)):
+ if options.dump_json and (options.verbose
+ or has_actions(options)):
parser.error("--dump-json can only be used alone.")
if options.all and not has_actions(options):
parser.error("--all requires an action.")
-
+
if options.check:
fail_count, test_count = doctest.testmod()
sys.exit(os.EX_OK if fail_count == 0 else 1)
-
+
try:
bus = dbus.SystemBus()
mandos_dbus_objc = bus.get_object(busname, server_path)
except dbus.exceptions.DBusException:
print("Could not connect to Mandos server", file=sys.stderr)
sys.exit(1)
-
+
mandos_serv = dbus.Interface(mandos_dbus_objc,
- dbus_interface = server_interface)
+ dbus_interface=server_interface)
mandos_serv_object_manager = dbus.Interface(
- mandos_dbus_objc, dbus_interface = dbus.OBJECT_MANAGER_IFACE)
-
- #block stderr since dbus library prints to stderr
+ mandos_dbus_objc, dbus_interface=dbus.OBJECT_MANAGER_IFACE)
+
+ # block stderr since dbus library prints to stderr
null = os.open(os.path.devnull, os.O_RDWR)
stderrcopy = os.dup(sys.stderr.fileno())
os.dup2(null, sys.stderr.fileno())
os.close(null)
try:
try:
- mandos_clients = { path: ifs_and_props[client_interface]
- for path, ifs_and_props in
- mandos_serv_object_manager
- .GetManagedObjects().items()
- if client_interface in ifs_and_props }
+ mandos_clients = {path: ifs_and_props[client_interface]
+ for path, ifs_and_props in
+ mandos_serv_object_manager
+ .GetManagedObjects().items()
+ if client_interface in ifs_and_props}
finally:
- #restore stderr
+ # restore stderr
os.dup2(stderrcopy, sys.stderr.fileno())
os.close(stderrcopy)
except dbus.exceptions.DBusException as e:
- print("Access denied: Accessing mandos server through D-Bus: {}"
- .format(e), file=sys.stderr)
+ print("Access denied: "
+ "Accessing mandos server through D-Bus: {}".format(e),
+ file=sys.stderr)
sys.exit(1)
-
+
# Compile dict of (clients: properties) to process
- clients={}
-
+ clients = {}
+
if options.all or not options.client:
- clients = { bus.get_object(busname, path): properties
- for path, properties in mandos_clients.items() }
+ clients = {bus.get_object(busname, path): properties
+ for path, properties in mandos_clients.items()}
else:
for name in options.client:
for path, client in mandos_clients.items():
@@ -393,7 +399,7 @@
print("Client not found on server: {!r}"
.format(name), file=sys.stderr)
sys.exit(1)
-
+
if not has_actions(options) and clients:
if options.verbose or options.dump_json:
keywords = ("Name", "Enabled", "Timeout", "LastCheckedOK",
@@ -406,36 +412,36 @@
"LastCheckerStatus")
else:
keywords = defaultkeywords
-
+
if options.dump_json:
json.dump({client["Name"]: {key:
bool(client[key])
if isinstance(client[key],
dbus.Boolean)
else client[key]
- for key in keywords }
- for client in clients.values() },
- fp = sys.stdout, indent = 4,
- separators = (',', ': '))
+ for key in keywords}
+ for client in clients.values()},
+ fp=sys.stdout, indent=4,
+ separators=(',', ': '))
print()
else:
print_clients(clients.values(), keywords)
else:
# Process each client in the list by all selected options
for client in clients:
-
+
def set_client_prop(prop, value):
"""Set a Client D-Bus property"""
client.Set(client_interface, prop, value,
dbus_interface=dbus.PROPERTIES_IFACE)
-
+
def set_client_prop_ms(prop, value):
"""Set a Client D-Bus property, converted
from a string to milliseconds."""
set_client_prop(prop,
string_to_delta(value).total_seconds()
* 1000)
-
+
if options.remove:
mandos_serv.RemoveClient(client.__dbus_object_path__)
if options.enable:
@@ -449,11 +455,11 @@
if options.stop_checker:
set_client_prop("CheckerRunning", dbus.Boolean(False))
if options.is_enabled:
- sys.exit(0 if client.Get(client_interface,
- "Enabled",
- dbus_interface=
- dbus.PROPERTIES_IFACE)
- else 1)
+ if client.Get(client_interface, "Enabled",
+ dbus_interface=dbus.PROPERTIES_IFACE):
+ sys.exit(0)
+ else:
+ sys.exit(1)
if options.checker is not None:
set_client_prop("Checker", options.checker)
if options.host is not None: