/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 at bsnet
  • Date: 2011-02-15 19:27:23 UTC
  • mto: (237.7.13 mandos)
  • mto: This revision was merged to the branch mainline in revision 282.
  • Revision ID: teddy@fukt.bsnet.se-20110215192723-qpftjhlvzadm5cjc
* mandos-ctl: Use unicode string literals.

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
4
4
# Mandos Monitor - Control and monitor the Mandos server
5
5
6
 
# Copyright © 2008-2011 Teddy Hogeborn
7
 
# Copyright © 2008-2011 Björn Påhlsson
 
6
# Copyright © 2008-2010 Teddy Hogeborn
 
7
# Copyright © 2008-2010 Björn Påhlsson
8
8
9
9
# This program is free software: you can redistribute it and/or modify
10
10
# it under the terms of the GNU General Public License as published by
19
19
# You should have received a copy of the GNU General Public License
20
20
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
21
21
22
 
# Contact the authors at <mandos@recompile.se>.
 
22
# Contact the authors at <mandos@fukt.bsnet.se>.
23
23
24
24
 
25
 
from __future__ import (division, absolute_import, print_function,
26
 
                        unicode_literals)
 
25
from __future__ import division, absolute_import, unicode_literals
27
26
 
28
27
import sys
29
28
import dbus
30
 
import argparse
 
29
from optparse import OptionParser
31
30
import locale
32
31
import datetime
33
32
import re
52
51
    "ApprovalDelay": "Approval Delay",
53
52
    "ApprovalDuration": "Approval Duration",
54
53
    "Checker": "Checker",
55
 
    "ExtendedTimeout" : "Extended Timeout"
56
54
    }
57
55
defaultkeywords = ("Name", "Enabled", "Timeout", "LastCheckedOK")
58
 
domain = "se.recompile"
 
56
domain = "se.bsnet.fukt"
59
57
busname = domain + ".Mandos"
60
58
server_path = "/"
61
59
server_interface = domain + ".Mandos"
62
60
client_interface = domain + ".Mandos.Client"
63
 
version = "1.4.1"
 
61
version = "1.2.3"
64
62
 
65
63
def timedelta_to_milliseconds(td):
66
64
    """Convert a datetime.timedelta object to milliseconds"""
77
75
                "seconds": td.seconds % 60,
78
76
                })
79
77
 
 
78
 
80
79
def string_to_delta(interval):
81
80
    """Parse a string and return a datetime.timedelta
82
 
    
 
81
 
83
82
    >>> string_to_delta("7d")
84
83
    datetime.timedelta(7)
85
84
    >>> string_to_delta("60s")
135
134
                                     clients))
136
135
                             for key in keywords)
137
136
    # Print header line
138
 
    print(format_string % tuple(tablewords[key] for key in keywords))
 
137
    print format_string % tuple(tablewords[key] for key in keywords)
139
138
    for client in clients:
140
 
        print(format_string % tuple(valuetostring(client[key], key)
141
 
                                    for key in keywords))
 
139
        print format_string % tuple(valuetostring(client[key], key)
 
140
                                    for key in keywords)
142
141
 
143
142
def has_actions(options):
144
143
    return any((options.enable,
150
149
                options.remove,
151
150
                options.checker is not None,
152
151
                options.timeout is not None,
153
 
                options.extended_timeout is not None,
154
152
                options.interval is not None,
155
153
                options.approved_by_default is not None,
156
154
                options.approval_delay is not None,
159
157
                options.secret is not None,
160
158
                options.approve,
161
159
                options.deny))
162
 
 
 
160
        
163
161
def main():
164
 
    parser = argparse.ArgumentParser()
165
 
    parser.add_argument("--version", action="version",
166
 
                        version = "%%prog %s" % version,
167
 
                        help="show version number and exit")
168
 
    parser.add_argument("-a", "--all", action="store_true",
169
 
                        help="Select all clients")
170
 
    parser.add_argument("-v", "--verbose", action="store_true",
171
 
                        help="Print all fields")
172
 
    parser.add_argument("-e", "--enable", action="store_true",
173
 
                        help="Enable client")
174
 
    parser.add_argument("-d", "--disable", action="store_true",
175
 
                        help="disable client")
176
 
    parser.add_argument("-b", "--bump-timeout", action="store_true",
177
 
                        help="Bump timeout for client")
178
 
    parser.add_argument("--start-checker", action="store_true",
179
 
                        help="Start checker for client")
180
 
    parser.add_argument("--stop-checker", action="store_true",
181
 
                        help="Stop checker for client")
182
 
    parser.add_argument("-V", "--is-enabled", action="store_true",
183
 
                        help="Check if client is enabled")
184
 
    parser.add_argument("-r", "--remove", action="store_true",
185
 
                        help="Remove client")
186
 
    parser.add_argument("-c", "--checker",
187
 
                        help="Set checker command for client")
188
 
    parser.add_argument("-t", "--timeout",
189
 
                        help="Set timeout for client")
190
 
    parser.add_argument("--extended-timeout",
191
 
                        help="Set extended timeout for client")
192
 
    parser.add_argument("-i", "--interval",
193
 
                        help="Set checker interval for client")
194
 
    parser.add_argument("--approve-by-default", action="store_true",
195
 
                        default=None, dest="approved_by_default",
196
 
                        help="Set client to be approved by default")
197
 
    parser.add_argument("--deny-by-default", action="store_false",
198
 
                        dest="approved_by_default",
199
 
                        help="Set client to be denied by default")
200
 
    parser.add_argument("--approval-delay",
201
 
                        help="Set delay before client approve/deny")
202
 
    parser.add_argument("--approval-duration",
203
 
                        help="Set duration of one client approval")
204
 
    parser.add_argument("-H", "--host", help="Set host for client")
205
 
    parser.add_argument("-s", "--secret", type=file,
206
 
                        help="Set password blob (file) for client")
207
 
    parser.add_argument("-A", "--approve", action="store_true",
208
 
                        help="Approve any current client request")
209
 
    parser.add_argument("-D", "--deny", action="store_true",
210
 
                        help="Deny any current client request")
211
 
    parser.add_argument("client", nargs="*", help="Client name")
212
 
    options = parser.parse_args()
213
 
    
214
 
    if has_actions(options) and not options.client and not options.all:
215
 
        parser.error("Options require clients names or --all.")
216
 
    if options.verbose and has_actions(options):
217
 
        parser.error("--verbose can only be used alone or with"
218
 
                     " --all.")
219
 
    if options.all and not has_actions(options):
220
 
        parser.error("--all requires an action.")
221
 
    
222
 
    try:
223
 
        bus = dbus.SystemBus()
224
 
        mandos_dbus_objc = bus.get_object(busname, server_path)
225
 
    except dbus.exceptions.DBusException:
226
 
        print("Could not connect to Mandos server",
227
 
              file=sys.stderr)
228
 
        sys.exit(1)
229
 
    
230
 
    mandos_serv = dbus.Interface(mandos_dbus_objc,
231
 
                                 dbus_interface = server_interface)
232
 
    
233
 
    #block stderr since dbus library prints to stderr
234
 
    null = os.open(os.path.devnull, os.O_RDWR)
235
 
    stderrcopy = os.dup(sys.stderr.fileno())
236
 
    os.dup2(null, sys.stderr.fileno())
237
 
    os.close(null)
238
 
    try:
239
 
        try:
240
 
            mandos_clients = mandos_serv.GetAllClientsWithProperties()
241
 
        finally:
242
 
            #restore stderr
243
 
            os.dup2(stderrcopy, sys.stderr.fileno())
244
 
            os.close(stderrcopy)
245
 
    except dbus.exceptions.DBusException, e:
246
 
        print("Access denied: Accessing mandos server through dbus.",
247
 
              file=sys.stderr)
248
 
        sys.exit(1)
249
 
    
250
 
    # Compile dict of (clients: properties) to process
251
 
    clients={}
252
 
    
253
 
    if options.all or not options.client:
254
 
        clients = dict((bus.get_object(busname, path), properties)
255
 
                       for path, properties in
256
 
                       mandos_clients.iteritems())
257
 
    else:
258
 
        for name in options.client:
259
 
            for path, client in mandos_clients.iteritems():
260
 
                if client["Name"] == name:
261
 
                    client_objc = bus.get_object(busname, path)
262
 
                    clients[client_objc] = client
263
 
                    break
 
162
        parser = OptionParser(version = "%%prog %s" % version)
 
163
        parser.add_option("-a", "--all", action="store_true",
 
164
                          help="Select all clients")
 
165
        parser.add_option("-v", "--verbose", action="store_true",
 
166
                          help="Print all fields")
 
167
        parser.add_option("-e", "--enable", action="store_true",
 
168
                          help="Enable client")
 
169
        parser.add_option("-d", "--disable", action="store_true",
 
170
                          help="disable client")
 
171
        parser.add_option("-b", "--bump-timeout", action="store_true",
 
172
                          help="Bump timeout for client")
 
173
        parser.add_option("--start-checker", action="store_true",
 
174
                          help="Start checker for client")
 
175
        parser.add_option("--stop-checker", action="store_true",
 
176
                          help="Stop checker for client")
 
177
        parser.add_option("-V", "--is-enabled", action="store_true",
 
178
                          help="Check if client is enabled")
 
179
        parser.add_option("-r", "--remove", action="store_true",
 
180
                          help="Remove client")
 
181
        parser.add_option("-c", "--checker", type="string",
 
182
                          help="Set checker command for client")
 
183
        parser.add_option("-t", "--timeout", type="string",
 
184
                          help="Set timeout for client")
 
185
        parser.add_option("-i", "--interval", type="string",
 
186
                          help="Set checker interval for client")
 
187
        parser.add_option("--approve-by-default", action="store_true",
 
188
                          dest="approved_by_default",
 
189
                          help="Set client to be approved by default")
 
190
        parser.add_option("--deny-by-default", action="store_false",
 
191
                          dest="approved_by_default",
 
192
                          help="Set client to be denied by default")
 
193
        parser.add_option("--approval-delay", type="string",
 
194
                          help="Set delay before client approve/deny")
 
195
        parser.add_option("--approval-duration", type="string",
 
196
                          help="Set duration of one client approval")
 
197
        parser.add_option("-H", "--host", type="string",
 
198
                          help="Set host for client")
 
199
        parser.add_option("-s", "--secret", type="string",
 
200
                          help="Set password blob (file) for client")
 
201
        parser.add_option("-A", "--approve", action="store_true",
 
202
                          help="Approve any current client request")
 
203
        parser.add_option("-D", "--deny", action="store_true",
 
204
                          help="Deny any current client request")
 
205
        options, client_names = parser.parse_args()
 
206
        
 
207
        if has_actions(options) and not client_names and not options.all:
 
208
            parser.error("Options require clients names or --all.")
 
209
        if options.verbose and has_actions(options):
 
210
            parser.error("--verbose can only be used alone or with"
 
211
                         " --all.")
 
212
        if options.all and not has_actions(options):
 
213
            parser.error("--all requires an action.")
 
214
        
 
215
        try:
 
216
            bus = dbus.SystemBus()
 
217
            mandos_dbus_objc = bus.get_object(busname, server_path)
 
218
        except dbus.exceptions.DBusException:
 
219
            print >> sys.stderr, "Could not connect to Mandos server"
 
220
            sys.exit(1)
 
221
    
 
222
        mandos_serv = dbus.Interface(mandos_dbus_objc,
 
223
                                     dbus_interface = server_interface)
 
224
 
 
225
        #block stderr since dbus library prints to stderr
 
226
        null = os.open(os.path.devnull, os.O_RDWR)
 
227
        stderrcopy = os.dup(sys.stderr.fileno())
 
228
        os.dup2(null, sys.stderr.fileno())
 
229
        os.close(null)
 
230
        try:
 
231
            try:
 
232
                mandos_clients = mandos_serv.GetAllClientsWithProperties()
 
233
            finally:
 
234
                #restore stderr
 
235
                os.dup2(stderrcopy, sys.stderr.fileno())
 
236
                os.close(stderrcopy)
 
237
        except dbus.exceptions.DBusException, e:
 
238
            print >> sys.stderr, "Access denied: Accessing mandos server through dbus."
 
239
            sys.exit(1)
 
240
            
 
241
        # Compile dict of (clients: properties) to process
 
242
        clients={}
 
243
        
 
244
        if options.all or not client_names:
 
245
            clients = dict((bus.get_object(busname, path), properties)
 
246
                           for path, properties in
 
247
                           mandos_clients.iteritems())
 
248
        else:
 
249
            for name in client_names:
 
250
                for path, client in mandos_clients.iteritems():
 
251
                    if client["Name"] == name:
 
252
                        client_objc = bus.get_object(busname, path)
 
253
                        clients[client_objc] = client
 
254
                        break
 
255
                else:
 
256
                    print >> sys.stderr, "Client not found on server: %r" % name
 
257
                    sys.exit(1)
 
258
            
 
259
        if not has_actions(options) and clients:
 
260
            if options.verbose:
 
261
                keywords = ("Name", "Enabled", "Timeout",
 
262
                            "LastCheckedOK", "Created", "Interval",
 
263
                            "Host", "Fingerprint", "CheckerRunning",
 
264
                            "LastEnabled", "ApprovalPending",
 
265
                            "ApprovedByDefault",
 
266
                            "LastApprovalRequest", "ApprovalDelay",
 
267
                            "ApprovalDuration", "Checker")
264
268
            else:
265
 
                print("Client not found on server: %r" % name,
266
 
                      file=sys.stderr)
267
 
                sys.exit(1)
268
 
    
269
 
    if not has_actions(options) and clients:
270
 
        if options.verbose:
271
 
            keywords = ("Name", "Enabled", "Timeout",
272
 
                        "LastCheckedOK", "Created", "Interval",
273
 
                        "Host", "Fingerprint", "CheckerRunning",
274
 
                        "LastEnabled", "ApprovalPending",
275
 
                        "ApprovedByDefault",
276
 
                        "LastApprovalRequest", "ApprovalDelay",
277
 
                        "ApprovalDuration", "Checker",
278
 
                        "ExtendedTimeout")
 
269
                keywords = defaultkeywords
 
270
            
 
271
            print_clients(clients.values(), keywords)
279
272
        else:
280
 
            keywords = defaultkeywords
281
 
        
282
 
        print_clients(clients.values(), keywords)
283
 
    else:
284
 
        # Process each client in the list by all selected options
285
 
        for client in clients:
286
 
            if options.remove:
287
 
                mandos_serv.RemoveClient(client.__dbus_object_path__)
288
 
            if options.enable:
289
 
                client.Enable(dbus_interface=client_interface)
290
 
            if options.disable:
291
 
                client.Disable(dbus_interface=client_interface)
292
 
            if options.bump_timeout:
293
 
                client.CheckedOK(dbus_interface=client_interface)
294
 
            if options.start_checker:
295
 
                client.StartChecker(dbus_interface=client_interface)
296
 
            if options.stop_checker:
297
 
                client.StopChecker(dbus_interface=client_interface)
298
 
            if options.is_enabled:
299
 
                sys.exit(0 if client.Get(client_interface,
300
 
                                         "Enabled",
301
 
                                         dbus_interface=
302
 
                                         dbus.PROPERTIES_IFACE)
303
 
                         else 1)
304
 
            if options.checker is not None:
305
 
                client.Set(client_interface, "Checker",
306
 
                           options.checker,
307
 
                           dbus_interface=dbus.PROPERTIES_IFACE)
308
 
            if options.host is not None:
309
 
                client.Set(client_interface, "Host", options.host,
310
 
                           dbus_interface=dbus.PROPERTIES_IFACE)
311
 
            if options.interval is not None:
312
 
                client.Set(client_interface, "Interval",
313
 
                           timedelta_to_milliseconds
314
 
                           (string_to_delta(options.interval)),
315
 
                           dbus_interface=dbus.PROPERTIES_IFACE)
316
 
            if options.approval_delay is not None:
317
 
                client.Set(client_interface, "ApprovalDelay",
318
 
                           timedelta_to_milliseconds
319
 
                           (string_to_delta(options.
320
 
                                            approval_delay)),
321
 
                           dbus_interface=dbus.PROPERTIES_IFACE)
322
 
            if options.approval_duration is not None:
323
 
                client.Set(client_interface, "ApprovalDuration",
324
 
                           timedelta_to_milliseconds
325
 
                           (string_to_delta(options.
326
 
                                            approval_duration)),
327
 
                           dbus_interface=dbus.PROPERTIES_IFACE)
328
 
            if options.timeout is not None:
329
 
                client.Set(client_interface, "Timeout",
330
 
                           timedelta_to_milliseconds
331
 
                           (string_to_delta(options.timeout)),
332
 
                           dbus_interface=dbus.PROPERTIES_IFACE)
333
 
            if options.extended_timeout is not None:
334
 
                client.Set(client_interface, "ExtendedTimeout",
335
 
                           timedelta_to_milliseconds
336
 
                           (string_to_delta(options.extended_timeout)),
337
 
                           dbus_interface=dbus.PROPERTIES_IFACE)
338
 
            if options.secret is not None:
339
 
                client.Set(client_interface, "Secret",
340
 
                           dbus.ByteArray(open(options.secret,
341
 
                                               "rb").read()),
342
 
                           dbus_interface=dbus.PROPERTIES_IFACE)
343
 
            if options.approved_by_default is not None:
344
 
                client.Set(client_interface, "ApprovedByDefault",
345
 
                           dbus.Boolean(options
346
 
                                        .approved_by_default),
347
 
                           dbus_interface=dbus.PROPERTIES_IFACE)
348
 
            if options.approve:
349
 
                client.Approve(dbus.Boolean(True),
350
 
                               dbus_interface=client_interface)
351
 
            elif options.deny:
352
 
                client.Approve(dbus.Boolean(False),
353
 
                               dbus_interface=client_interface)
 
273
            # Process each client in the list by all selected options
 
274
            for client in clients:
 
275
                if options.remove:
 
276
                    mandos_serv.RemoveClient(client.__dbus_object_path__)
 
277
                if options.enable:
 
278
                    client.Enable(dbus_interface=client_interface)
 
279
                if options.disable:
 
280
                    client.Disable(dbus_interface=client_interface)
 
281
                if options.bump_timeout:
 
282
                    client.CheckedOK(dbus_interface=client_interface)
 
283
                if options.start_checker:
 
284
                    client.StartChecker(dbus_interface=client_interface)
 
285
                if options.stop_checker:
 
286
                    client.StopChecker(dbus_interface=client_interface)
 
287
                if options.is_enabled:
 
288
                    sys.exit(0 if client.Get(client_interface,
 
289
                                             "Enabled",
 
290
                                             dbus_interface=dbus.PROPERTIES_IFACE)
 
291
                             else 1)
 
292
                if options.checker:
 
293
                    client.Set(client_interface, "Checker", options.checker,
 
294
                               dbus_interface=dbus.PROPERTIES_IFACE)
 
295
                if options.host:
 
296
                    client.Set(client_interface, "Host", options.host,
 
297
                               dbus_interface=dbus.PROPERTIES_IFACE)
 
298
                if options.interval:
 
299
                    client.Set(client_interface, "Interval",
 
300
                               timedelta_to_milliseconds
 
301
                               (string_to_delta(options.interval)),
 
302
                               dbus_interface=dbus.PROPERTIES_IFACE)
 
303
                if options.approval_delay:
 
304
                    client.Set(client_interface, "ApprovalDelay",
 
305
                               timedelta_to_milliseconds
 
306
                               (string_to_delta(options.
 
307
                                                approval_delay)),
 
308
                               dbus_interface=dbus.PROPERTIES_IFACE)
 
309
                if options.approval_duration:
 
310
                    client.Set(client_interface, "ApprovalDuration",
 
311
                               timedelta_to_milliseconds
 
312
                               (string_to_delta(options.
 
313
                                                approval_duration)),
 
314
                               dbus_interface=dbus.PROPERTIES_IFACE)
 
315
                if options.timeout:
 
316
                    client.Set(client_interface, "Timeout",
 
317
                               timedelta_to_milliseconds
 
318
                               (string_to_delta(options.timeout)),
 
319
                               dbus_interface=dbus.PROPERTIES_IFACE)
 
320
                if options.secret:
 
321
                    client.Set(client_interface, "Secret",
 
322
                               dbus.ByteArray(open(options.secret,
 
323
                                                   "rb").read()),
 
324
                               dbus_interface=dbus.PROPERTIES_IFACE)
 
325
                if options.approved_by_default is not None:
 
326
                    client.Set(client_interface, "ApprovedByDefault",
 
327
                               dbus.Boolean(options
 
328
                                            .approved_by_default),
 
329
                               dbus_interface=dbus.PROPERTIES_IFACE)
 
330
                if options.approve:
 
331
                    client.Approve(dbus.Boolean(True),
 
332
                                   dbus_interface=client_interface)
 
333
                elif options.deny:
 
334
                    client.Approve(dbus.Boolean(False),
 
335
                                   dbus_interface=client_interface)
354
336
 
355
337
if __name__ == "__main__":
356
338
    main()