4
4
# Mandos Monitor - Control and monitor the Mandos server
6
# Copyright © 2009-2012 Teddy Hogeborn
7
# Copyright © 2009-2012 Björn Påhlsson
6
# Copyright © 2009-2011 Teddy Hogeborn
7
# Copyright © 2009-2011 Björn Påhlsson
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/>.
22
# Contact the authors at <mandos@recompile.se>.
22
# Contact the authors at <mandos@fukt.bsnet.se>.
25
25
from __future__ import (division, absolute_import, print_function,
49
49
logging.getLogger('dbus.proxies').setLevel(logging.CRITICAL)
51
51
# Some useful constants
52
domain = 'se.recompile'
52
domain = 'se.bsnet.fukt'
53
53
server_interface = domain + '.Mandos'
54
54
client_interface = domain + '.Mandos.Client'
57
57
# Always run in monochrome mode
58
58
urwid.curses_display.curses.has_colors = lambda : False
132
132
self._update_timer_callback_tag = None
133
133
self._update_timer_callback_lock = 0
134
self.last_checker_failed = False
135
136
# The widget shown normally
136
137
self._text_widget = urwid.Text("")
145
146
last_checked_ok = isoformat_to_datetime(self.properties
146
147
["LastCheckedOK"])
148
if last_checked_ok is None:
149
self.last_checker_failed = True
151
self.last_checker_failed = ((datetime.datetime.utcnow()
148
if self.properties ["LastCheckerStatus"] != 0:
158
if self.last_checker_failed:
149
159
self.using_timer(True)
151
161
if self.need_approval:
180
190
if property == "ApprovalPending":
181
191
using_timer(bool(value))
182
if property == "LastCheckerStatus":
183
using_timer(value != 0)
184
#self.logger('Checker for client %s (command "%s")'
186
# % (self.properties["Name"], command))
188
193
def using_timer(self, flag):
189
194
"""Call this method with True or False when timer should be
190
195
activated or deactivated.
206
210
def checker_completed(self, exitstatus, condition, command):
207
211
if exitstatus == 0:
212
if self.last_checker_failed:
213
self.last_checker_failed = False
214
self.using_timer(False)
215
#self.logger('Checker for client %s (command "%s")'
217
# % (self.properties["Name"], command))
221
if not self.last_checker_failed:
222
self.last_checker_failed = True
223
self.using_timer(True)
211
224
if os.WIFEXITED(condition):
212
225
self.logger('Checker for client %s (command "%s")'
213
226
' failed with exit code %s'
230
243
def checker_started(self, command):
231
"""Server signals that a checker started. This could be useful
232
to log in the future. """
233
244
#self.logger('Client %s started checker "%s"'
234
245
# % (self.properties["Name"], unicode(command)))
237
248
def got_secret(self):
249
self.last_checker_failed = False
238
250
self.logger('Client %s received its secret'
239
251
% self.properties["Name"])
302
314
message = "Denial in %s. (a)pprove?"
303
315
message = message % unicode(timer).rsplit(".", 1)[0]
304
elif self.properties["LastCheckerStatus"] != 0:
305
# When checker has failed, print a timer until client expires
306
expires = self.properties["Expires"]
308
timer = datetime.timedelta(0)
310
expires = datetime.datetime.strptime(expires,
311
'%Y-%m-%dT%H:%M:%S.%f')
312
timer = expires - datetime.datetime.utcnow()
316
elif self.last_checker_failed:
317
timeout = datetime.timedelta(milliseconds
320
last_ok = isoformat_to_datetime(
321
max((self.properties["LastCheckedOK"]
322
or self.properties["Created"]),
323
self.properties["LastEnabled"]))
324
timer = timeout - (datetime.datetime.utcnow() - last_ok)
313
325
message = ('A checker has failed! Time until client'
314
326
' gets disabled: %s'
315
327
% unicode(timer).rsplit(".", 1)[0])
485
496
self.busname = domain + '.Mandos'
486
497
self.main_loop = gobject.MainLoop()
498
self.bus = dbus.SystemBus()
499
mandos_dbus_objc = self.bus.get_object(
500
self.busname, "/", follow_name_owner_changes=True)
501
self.mandos_serv = dbus.Interface(mandos_dbus_objc,
505
mandos_clients = (self.mandos_serv
506
.GetAllClientsWithProperties())
507
except dbus.exceptions.DBusException:
508
mandos_clients = dbus.Dictionary()
511
.connect_to_signal("ClientRemoved",
512
self.find_and_remove_client,
513
dbus_interface=server_interface,
516
.connect_to_signal("ClientAdded",
518
dbus_interface=server_interface,
521
.connect_to_signal("ClientNotFound",
522
self.client_not_found,
523
dbus_interface=server_interface,
525
for path, client in mandos_clients.iteritems():
526
client_proxy_object = self.bus.get_object(self.busname,
528
self.add_client(MandosClientWidget(server_proxy_object
531
=client_proxy_object,
488
541
def client_not_found(self, fingerprint, address):
489
542
self.log_message(("Client with address %s and fingerprint %s"
595
649
"""Start the main loop and exit when it's done."""
596
self.bus = dbus.SystemBus()
597
mandos_dbus_objc = self.bus.get_object(
598
self.busname, "/", follow_name_owner_changes=True)
599
self.mandos_serv = dbus.Interface(mandos_dbus_objc,
603
mandos_clients = (self.mandos_serv
604
.GetAllClientsWithProperties())
605
except dbus.exceptions.DBusException:
606
mandos_clients = dbus.Dictionary()
609
.connect_to_signal("ClientRemoved",
610
self.find_and_remove_client,
611
dbus_interface=server_interface,
614
.connect_to_signal("ClientAdded",
616
dbus_interface=server_interface,
619
.connect_to_signal("ClientNotFound",
620
self.client_not_found,
621
dbus_interface=server_interface,
623
for path, client in mandos_clients.iteritems():
624
client_proxy_object = self.bus.get_object(self.busname,
626
self.add_client(MandosClientWidget(server_proxy_object
629
=client_proxy_object,
640
651
self._input_callback_tag = (gobject.io_add_watch
641
652
(sys.stdin.fileno(),