/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

  • Committer: Teddy Hogeborn
  • Date: 2008-07-20 06:33:48 UTC
  • Revision ID: teddy@fukt.bsnet.se-20080720063348-jscgy5p0itrgvlo8
* mandos-clients.conf ([foo]): Uncommented.
  ([foo]/secret): New.
  ([foo]/secfile): Commented out.
  ([foo]/checker): Changed to "fping -q -- %%(fqdn)s".
  ([foo]/timeout): New.

* server.py: New modeline for Python and Emacs.  Set a logging format.
  (Client.__init__): Bug fix: Choose either the value from the options
                     object or pass the argument through string_to_delta
                     for both "timeout" and "interval".
  (Client.checker_callback): Bug fix: Do not log spurious "Checker for
                             <foo> failed" messages.
  (Client.start_checker): Moved "Starting checker" log message down to
                          just before actually starting the subprocess.
                          Do not redirect the subprocesses' stdout to a
                          pipe.
  (peer_certificate, fingerprint): Added docstrings.
  (entry_group_state_changed): Call "killme()" instead of
                               "main_loop.quit()".
  (daemon, killme): New functions.
  (exitstatus, main_loop_started): New global variables.
  (__main__): Removed the "--cert", "--key", "--ca", and "--crl"
              options.  Removed the sleep command from the default
              checker.  Add a console logger in debug mode.  Call
              "killme()" instead of "main_loop.quit()" when there are no
              more clients.  Call "daemon()" if not in debug mode.
              Register "cleanup()" to run at exit.  Ignore some
              signals.  Catch DBusException to detect another running
              server and exit cleanly.  Exit with "exitstatus".
  (cleanup): New function.

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