/mandos/release

To get this branch, use:
bzr branch http://bzr.recompile.se/loggerhead/mandos/release

« back to all changes in this revision

Viewing changes to mandos-ctl

First version of a somewhat complete D-Bus server interface.  Also
change user/group name to "_mandos".

* debian/mandos.postinst: Rename old "mandos" user and group to
                          "_mandos"; create "_mandos" user and group
                          if none exist.
* debian/mandos-client.postinst: - '' -

* initramfs-tools-hook: Try "_mandos" before "mandos" as user and
                        group name.

* mandos (_datetime_to_dbus_struct): New; was previously local.
  (Client.started): Renamed to "last_started".  All users changed.
  (Client.started): New; boolean.
  (Client.dbus_object_path): New.
  (Client.check_command): Renamed to "checker_command".  All users
                          changed.
  (Client.__init__): Set and use "self.dbus_object_path".  Set
                     "self.started".
  (Client.start): Update "self.started".  Emit "self.PropertyChanged"
                  signals for both "started" and "last_started".
  (Client.stop): Update "self.started".  Emit "self.PropertyChanged"
                 signal for "started".
  (Client.checker_callback): Take additional "command" argument.  All
                             callers changed. Emit
                             "self.PropertyChanged" signal.
  (Client.bump_timeout): Emit "self.PropertyChanged" signal for
                         "last_checked_ok".
  (Client.start_checker): Emit "self.PropertyChanged" signal for
                          "checker_running".
  (Client.stop_checker): Emit "self.PropertyChanged" signal for
                         "checker_running".
  (Client.still_valid): Bug fix: use "getattr(self, started, False)"
                        instead of "self.started" in case this client
                        object is so new that the "started" attribute
                        has not been created yet.
  (Client.IntervalChanged, Client.CheckerIsRunning, Client.GetChecker,
  Client.GetCreated, Client.GetFingerprint, Client.GetHost,
  Client.GetInterval, Client.GetName, Client.GetStarted,
  Client.GetTimeout, Client.StateChanged, Client.TimeoutChanged):
  Removed; all callers changed.
  (Client.CheckerCompleted): Add "condition" and "command" arguments.
                             All callers changed.
  (Client.GetAllProperties, Client.PropertyChanged): New.
  (Client.StillValid): Renamed to "IsStillValid".
  (Client.StartChecker): Changed to its own function to avoid the
                         return value from "Client.start_checker()".
  (Client.Stop): Changed to its own function to avoid the return value
                 from "Client.stop()".
  (main): Try "_mandos" before "mandos" as user and group name.
          Removed inner function "remove_from_clients".  New inner
          class "MandosServer".

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#!/usr/bin/python
2
 
# -*- mode: python; coding: utf-8 -*-
3
 
 
4
 
from __future__ import division
5
 
import sys
6
 
import dbus
7
 
from optparse import OptionParser
8
 
import locale
9
 
import datetime
10
 
import re
11
 
 
12
 
locale.setlocale(locale.LC_ALL, u'')
13
 
 
14
 
tablewords = {
15
 
    'name': u'Name',
16
 
    'enabled': u'Enabled',
17
 
    'timeout': u'Timeout',
18
 
    'last_checked_ok': u'Last Successful Check',
19
 
    'created': u'Created',
20
 
    'interval': u'Interval',
21
 
    'host': u'Host',
22
 
    'fingerprint': u'Fingerprint',
23
 
    'checker_running': u'Check Is Running',
24
 
    'last_enabled': u'Last Enabled',
25
 
    'checker': u'Checker',
26
 
    }
27
 
defaultkeywords = ('name', 'enabled', 'timeout', 'last_checked_ok',
28
 
                   'checker')
29
 
busname = 'org.mandos-system.Mandos'
30
 
server_path = '/Mandos'
31
 
server_interface = 'org.mandos_system.Mandos'
32
 
client_interface = 'org.mandos_system.Mandos.Client'
33
 
version = "1.0.5"
34
 
 
35
 
bus = dbus.SystemBus()
36
 
mandos_dbus_objc = bus.get_object(busname, server_path)
37
 
mandos_serv = dbus.Interface(mandos_dbus_objc,
38
 
                             dbus_interface = server_interface)
39
 
mandos_clients = mandos_serv.GetAllClientsWithProperties()
40
 
 
41
 
def datetime_to_milliseconds(dt):
42
 
    "Return the 'timeout' attribute in milliseconds"
43
 
    return ((dt.days * 24 * 60 * 60 * 1000)
44
 
            + (dt.seconds * 1000)
45
 
            + (dt.microseconds // 1000))
46
 
 
47
 
def milliseconds_to_string(ms):
48
 
    td = datetime.timedelta(0, 0, 0, ms)
49
 
    return "%s%02d:%02d:%02d" % (("%dT" % td.days) if td.days else "", # days
50
 
                           td.seconds // 3600,        # hours
51
 
                           (td.seconds % 3600) // 60, # minutes
52
 
                           (td.seconds % 60))         # seconds
53
 
 
54
 
 
55
 
def string_to_delta(interval):
56
 
    """Parse a string and return a datetime.timedelta
57
 
 
58
 
    >>> string_to_delta('7d')
59
 
    datetime.timedelta(7)
60
 
    >>> string_to_delta('60s')
61
 
    datetime.timedelta(0, 60)
62
 
    >>> string_to_delta('60m')
63
 
    datetime.timedelta(0, 3600)
64
 
    >>> string_to_delta('24h')
65
 
    datetime.timedelta(1)
66
 
    >>> string_to_delta(u'1w')
67
 
    datetime.timedelta(7)
68
 
    >>> string_to_delta('5m 30s')
69
 
    datetime.timedelta(0, 330)
70
 
    """
71
 
    timevalue = datetime.timedelta(0)
72
 
    regexp = re.compile("\d+[dsmhw]")
73
 
    
74
 
    for s in regexp.findall(interval):
75
 
        try:
76
 
            suffix = unicode(s[-1])
77
 
            value = int(s[:-1])
78
 
            if suffix == u"d":
79
 
                delta = datetime.timedelta(value)
80
 
            elif suffix == u"s":
81
 
                delta = datetime.timedelta(0, value)
82
 
            elif suffix == u"m":
83
 
                delta = datetime.timedelta(0, 0, 0, 0, value)
84
 
            elif suffix == u"h":
85
 
                delta = datetime.timedelta(0, 0, 0, 0, 0, value)
86
 
            elif suffix == u"w":
87
 
                delta = datetime.timedelta(0, 0, 0, 0, 0, 0, value)
88
 
            else:
89
 
                raise ValueError
90
 
        except (ValueError, IndexError):
91
 
            raise ValueError
92
 
        timevalue += delta
93
 
    return timevalue
94
 
 
95
 
def print_clients(clients):
96
 
    def valuetostring(value, keyword):
97
 
        if type(value) is dbus.Boolean:
98
 
            return u"Yes" if value else u"No"
99
 
        if keyword in ("timeout", "interval"):
100
 
            return milliseconds_to_string(value)
101
 
        return unicode(value)
102
 
    
103
 
    format_string = u' '.join(u'%%-%ds' %
104
 
                              max(len(tablewords[key]),
105
 
                                  max(len(valuetostring(client[key], key))
106
 
                                      for client in
107
 
                                      clients))
108
 
                              for key in keywords)
109
 
    print format_string % tuple(tablewords[key] for key in keywords) 
110
 
    for client in clients:
111
 
        print format_string % tuple(valuetostring(client[key], key)
112
 
                                    for key in keywords)
113
 
 
114
 
parser = OptionParser(version = "%%prog %s" % version)
115
 
parser.add_option("-a", "--all", action="store_true",
116
 
                  help="Print all fields")
117
 
parser.add_option("-e", "--enable", action="store_true",
118
 
                  help="Enable specified client")
119
 
parser.add_option("-d", "--disable", action="store_true",
120
 
                  help="disable specified client")
121
 
parser.add_option("-b", "--bump-timeout", action="store_true",
122
 
                  help="Bump timeout of specified client")
123
 
parser.add_option("--start-checker", action="store_true",
124
 
                  help="Start checker for specified client")
125
 
parser.add_option("--stop-checker", action="store_true",
126
 
                  help="Stop checker for specified client")
127
 
parser.add_option("-v", "--is-valid", action="store_true",
128
 
                  help="Stop checker for specified client")
129
 
parser.add_option("-c", "--checker", type="string",
130
 
                  help="Set checker command for specified client")
131
 
parser.add_option("-t", "--timeout", type="string",
132
 
                  help="Set timeout for specified client")
133
 
parser.add_option("-i", "--interval", type="string",
134
 
                  help="Set checker interval for specified client")
135
 
parser.add_option("-H", "--host", type="string",
136
 
                  help="Set host for specified client")
137
 
parser.add_option("-s", "--secret", type="string",
138
 
                  help="Set password blob (file) for specified client")
139
 
options, client_names = parser.parse_args()
140
 
 
141
 
clients=[]
142
 
for name in client_names:
143
 
    for path, client in mandos_clients.iteritems():
144
 
        if client['name'] == name:
145
 
            client_objc = bus.get_object(busname, path)
146
 
            clients.append(dbus.Interface(client_objc,
147
 
                                          dbus_interface
148
 
                                          = client_interface))
149
 
            break
150
 
    else:
151
 
        print >> sys.stderr, "Client not found on server: %r" % name
152
 
        sys.exit(1)
153
 
 
154
 
if not clients:
155
 
    keywords = defaultkeywords
156
 
    if options.all:
157
 
        keywords = ('name', 'enabled', 'timeout', 'last_checked_ok',
158
 
                    'created', 'interval', 'host', 'fingerprint',
159
 
                    'checker_running', 'last_enabled', 'checker')
160
 
    print_clients(mandos_clients.values())
161
 
    
162
 
for client in clients:
163
 
    if options.enable:
164
 
        client.Enable()
165
 
    if options.disable:
166
 
        client.Disable()
167
 
    if options.bump_timeout:
168
 
        client.BumpTimeout()
169
 
    if options.start_checker:
170
 
        client.StartChecker()
171
 
    if options.stop_checker:
172
 
        client.StopChecker()
173
 
    if options.is_valid:
174
 
        sys.exit(0 if client.IsStillValid() else 1)
175
 
    if options.checker:
176
 
        client.SetChecker(options.checker)
177
 
    if options.host:
178
 
        client.SetHost(options.host)
179
 
    if options.interval:
180
 
        client.SetInterval(datetime_to_milliseconds
181
 
                           (string_to_delta(options.interval)))
182
 
    if options.timeout:
183
 
        client.SetTimeout(datetime_to_milliseconds
184
 
                          (string_to_delta(options.timeout)))
185
 
    if options.secret:
186
 
        client.SetSecret(dbus.ByteArray(open(options.secret, 'rb').read()))
187