/mandos/trunk

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

« back to all changes in this revision

Viewing changes to mandos-ctl

  • Committer: Björn Påhlsson
  • Date: 2008-07-20 02:52:20 UTC
  • Revision ID: belorn@braxen-20080720025220-r5u0388uy9iu23h6
Added following support:
Pluginbased client handler
rewritten Mandos client
       Avahi instead of udp server discovery
       openpgp encrypted key support
Passprompt stand alone application for direct console input
Added logging for Mandos server

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
 
domain = 'se.bsnet.fukt'
29
 
busname = domain + '.Mandos'
30
 
server_path = '/'
31
 
server_interface = domain + '.Mandos'
32
 
client_interface = domain + '.Mandos.Client'
33
 
version = "1.0.14"
34
 
try:
35
 
    bus = dbus.SystemBus()
36
 
    mandos_dbus_objc = bus.get_object(busname, server_path)
37
 
except dbus.exceptions.DBusException:
38
 
    sys.exit(1)
39
 
    
40
 
mandos_serv = dbus.Interface(mandos_dbus_objc,
41
 
                             dbus_interface = server_interface)
42
 
mandos_clients = mandos_serv.GetAllClientsWithProperties()
43
 
 
44
 
def timedelta_to_milliseconds(td):
45
 
    "Convert a datetime.timedelta object to milliseconds"
46
 
    return ((td.days * 24 * 60 * 60 * 1000)
47
 
            + (td.seconds * 1000)
48
 
            + (td.microseconds // 1000))
49
 
 
50
 
def milliseconds_to_string(ms):
51
 
    td = datetime.timedelta(0, 0, 0, ms)
52
 
    return (u"%(days)s%(hours)02d:%(minutes)02d:%(seconds)02d"
53
 
            % { "days": "%dT" % td.days if td.days else "",
54
 
                "hours": td.seconds // 3600,
55
 
                "minutes": (td.seconds % 3600) // 60,
56
 
                "seconds": td.seconds % 60,
57
 
                })
58
 
 
59
 
 
60
 
def string_to_delta(interval):
61
 
    """Parse a string and return a datetime.timedelta
62
 
 
63
 
    >>> string_to_delta('7d')
64
 
    datetime.timedelta(7)
65
 
    >>> string_to_delta('60s')
66
 
    datetime.timedelta(0, 60)
67
 
    >>> string_to_delta('60m')
68
 
    datetime.timedelta(0, 3600)
69
 
    >>> string_to_delta('24h')
70
 
    datetime.timedelta(1)
71
 
    >>> string_to_delta(u'1w')
72
 
    datetime.timedelta(7)
73
 
    >>> string_to_delta('5m 30s')
74
 
    datetime.timedelta(0, 330)
75
 
    """
76
 
    timevalue = datetime.timedelta(0)
77
 
    regexp = re.compile("\d+[dsmhw]")
78
 
    
79
 
    for s in regexp.findall(interval):
80
 
        try:
81
 
            suffix = unicode(s[-1])
82
 
            value = int(s[:-1])
83
 
            if suffix == u"d":
84
 
                delta = datetime.timedelta(value)
85
 
            elif suffix == u"s":
86
 
                delta = datetime.timedelta(0, value)
87
 
            elif suffix == u"m":
88
 
                delta = datetime.timedelta(0, 0, 0, 0, value)
89
 
            elif suffix == u"h":
90
 
                delta = datetime.timedelta(0, 0, 0, 0, 0, value)
91
 
            elif suffix == u"w":
92
 
                delta = datetime.timedelta(0, 0, 0, 0, 0, 0, value)
93
 
            else:
94
 
                raise ValueError
95
 
        except (ValueError, IndexError):
96
 
            raise ValueError
97
 
        timevalue += delta
98
 
    return timevalue
99
 
 
100
 
def print_clients(clients):
101
 
    def valuetostring(value, keyword):
102
 
        if type(value) is dbus.Boolean:
103
 
            return u"Yes" if value else u"No"
104
 
        if keyword in (u"timeout", u"interval"):
105
 
            return milliseconds_to_string(value)
106
 
        return unicode(value)
107
 
    
108
 
    # Create format string to print table rows
109
 
    format_string = u' '.join(u'%%-%ds' %
110
 
                              max(len(tablewords[key]),
111
 
                                  max(len(valuetostring(client[key], key))
112
 
                                      for client in
113
 
                                      clients))
114
 
                              for key in keywords)
115
 
    # Print header line
116
 
    print format_string % tuple(tablewords[key] for key in keywords)
117
 
    for client in clients:
118
 
        print format_string % tuple(valuetostring(client[key], key)
119
 
                                    for key in keywords)
120
 
 
121
 
parser = OptionParser(version = "%%prog %s" % version)
122
 
parser.add_option("-a", "--all", action="store_true",
123
 
                  help="Print all fields")
124
 
parser.add_option("-e", "--enable", action="store_true",
125
 
                  help="Enable client")
126
 
parser.add_option("-d", "--disable", action="store_true",
127
 
                  help="disable client")
128
 
parser.add_option("-b", "--bump-timeout", action="store_true",
129
 
                  help="Bump timeout for client")
130
 
parser.add_option("--start-checker", action="store_true",
131
 
                  help="Start checker for client")
132
 
parser.add_option("--stop-checker", action="store_true",
133
 
                  help="Stop checker for client")
134
 
parser.add_option("-V", "--is-enabled", action="store_true",
135
 
                  help="Check if client is enabled")
136
 
parser.add_option("-r", "--remove", action="store_true",
137
 
                  help="Remove client")
138
 
parser.add_option("-c", "--checker", type="string",
139
 
                  help="Set checker command for client")
140
 
parser.add_option("-t", "--timeout", type="string",
141
 
                  help="Set timeout for client")
142
 
parser.add_option("-i", "--interval", type="string",
143
 
                  help="Set checker interval for client")
144
 
parser.add_option("-H", "--host", type="string",
145
 
                  help="Set host for client")
146
 
parser.add_option("-s", "--secret", type="string",
147
 
                  help="Set password blob (file) for client")
148
 
parser.add_option("-A", "--approve", action="store_true",
149
 
                  help="Approve any current client request")
150
 
parser.add_option("-D", "--deny", action="store_true",
151
 
                  help="Deny any current client request")
152
 
options, client_names = parser.parse_args()
153
 
 
154
 
# Compile list of clients to process
155
 
clients=[]
156
 
for name in client_names:
157
 
    for path, client in mandos_clients.iteritems():
158
 
        if client['name'] == name:
159
 
            client_objc = bus.get_object(busname, path)
160
 
            clients.append(client_objc)
161
 
            break
162
 
    else:
163
 
        print >> sys.stderr, "Client not found on server: %r" % name
164
 
        sys.exit(1)
165
 
 
166
 
if not clients and mandos_clients.values():
167
 
    keywords = defaultkeywords
168
 
    if options.all:
169
 
        keywords = ('name', 'enabled', 'timeout', 'last_checked_ok',
170
 
                    'created', 'interval', 'host', 'fingerprint',
171
 
                    'checker_running', 'last_enabled', 'checker')
172
 
    print_clients(mandos_clients.values())
173
 
 
174
 
# Process each client in the list by all selected options
175
 
for client in clients:
176
 
    if options.remove:
177
 
        mandos_serv.RemoveClient(client.__dbus_object_path__)
178
 
    if options.enable:
179
 
        client.Enable(dbus_interface=client_interface)
180
 
    if options.disable:
181
 
        client.Disable(dbus_interface=client_interface)
182
 
    if options.bump_timeout:
183
 
        client.CheckedOK(dbus_interface=client_interface)
184
 
    if options.start_checker:
185
 
        client.StartChecker(dbus_interface=client_interface)
186
 
    if options.stop_checker:
187
 
        client.StopChecker(dbus_interface=client_interface)
188
 
    if options.is_enabled:
189
 
        sys.exit(0 if client.Get(client_interface,
190
 
                                 u"enabled",
191
 
                                 dbus_interface=dbus.PROPERTIES_IFACE)
192
 
                 else 1)
193
 
    if options.checker:
194
 
        client.Set(client_interface, u"checker", options.checker,
195
 
                   dbus_interface=dbus.PROPERTIES_IFACE)
196
 
    if options.host:
197
 
        client.Set(client_interface, u"host", options.host,
198
 
                   dbus_interface=dbus.PROPERTIES_IFACE)
199
 
    if options.interval:
200
 
        client.Set(client_interface, u"interval",
201
 
                   timedelta_to_milliseconds
202
 
                   (string_to_delta(options.interval)),
203
 
                   dbus_interface=dbus.PROPERTIES_IFACE)
204
 
    if options.timeout:
205
 
        client.Set(client_interface, u"timeout",
206
 
                   timedelta_to_milliseconds(string_to_delta
207
 
                                             (options.timeout)),
208
 
                   dbus_interface=dbus.PROPERTIES_IFACE)
209
 
    if options.secret:
210
 
        client.Set(client_interface, u"secret",
211
 
                   dbus.ByteArray(open(options.secret, u'rb').read()),
212
 
                   dbus_interface=dbus.PROPERTIES_IFACE)
213
 
    if options.approve:
214
 
        client.Approve(dbus.Boolean(True), dbus_interface=client_interface)
215
 
    if options.deny:
216
 
        client.Approve(dbus.Boolean(False), dbus_interface=client_interface)