/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-monitor

* mandos: Use all new builtins.
* mandos-ctl: - '' -
* mandos-monitor: - '' -

Show diffs side-by-side

added added

removed removed

Lines of Context:
55
55
domain = 'se.recompile'
56
56
server_interface = domain + '.Mandos'
57
57
client_interface = domain + '.Mandos.Client'
58
 
version = "1.5.5"
 
58
version = "1.5.3"
59
59
 
60
60
# Always run in monochrome mode
61
61
urwid.curses_display.curses.has_colors = lambda : False
86
86
    properties and calls a hook function when any of them are
87
87
    changed.
88
88
    """
89
 
    def __init__(self, proxy_object=None, properties=None, **kwargs):
 
89
    def __init__(self, proxy_object=None, *args, **kwargs):
90
90
        self.proxy = proxy_object # Mandos Client proxy object
91
 
        self.properties = dict() if properties is None else properties
 
91
        
 
92
        self.properties = dict()
92
93
        self.property_changed_match = (
93
94
            self.proxy.connect_to_signal("PropertyChanged",
94
 
                                         self._property_changed,
 
95
                                         self.property_changed,
95
96
                                         client_interface,
96
97
                                         byte_arrays=True))
97
98
        
98
 
        if properties is None:
99
 
            self.properties.update(
100
 
                self.proxy.GetAll(client_interface,
101
 
                                  dbus_interface
102
 
                                  = dbus.PROPERTIES_IFACE))
103
 
        
104
 
        super(MandosClientPropertyCache, self).__init__(**kwargs)
105
 
    
106
 
    def _property_changed(self, property, value):
107
 
        """Helper which takes positional arguments"""
108
 
        return self.property_changed(property=property, value=value)
 
99
        self.properties.update(
 
100
            self.proxy.GetAll(client_interface,
 
101
                              dbus_interface = dbus.PROPERTIES_IFACE))
 
102
 
 
103
        #XXX This breaks good super behaviour
 
104
#        super(MandosClientPropertyCache, self).__init__(
 
105
#            *args, **kwargs)
109
106
    
110
107
    def property_changed(self, property=None, value=None):
111
108
        """This is called whenever we get a PropertyChanged signal
114
111
        # Update properties dict with new value
115
112
        self.properties[property] = value
116
113
    
117
 
    def delete(self):
 
114
    def delete(self, *args, **kwargs):
118
115
        self.property_changed_match.remove()
 
116
        super(MandosClientPropertyCache, self).__init__(
 
117
            *args, **kwargs)
119
118
 
120
119
 
121
120
class MandosClientWidget(urwid.FlowWidget, MandosClientPropertyCache):
123
122
    """
124
123
    
125
124
    def __init__(self, server_proxy_object=None, update_hook=None,
126
 
                 delete_hook=None, logger=None, **kwargs):
 
125
                 delete_hook=None, logger=None, *args, **kwargs):
127
126
        # Called on update
128
127
        self.update_hook = update_hook
129
128
        # Called on delete
134
133
        self.logger = logger
135
134
        
136
135
        self._update_timer_callback_tag = None
 
136
        self._update_timer_callback_lock = 0
137
137
        
138
138
        # The widget shown normally
139
139
        self._text_widget = urwid.Text("")
140
140
        # The widget shown when we have focus
141
141
        self._focus_text_widget = urwid.Text("")
142
 
        super(MandosClientWidget, self).__init__(**kwargs)
 
142
        super(MandosClientWidget, self).__init__(
 
143
            update_hook=update_hook, delete_hook=delete_hook,
 
144
            *args, **kwargs)
143
145
        self.update()
144
146
        self.opened = False
145
147
        
 
148
        last_checked_ok = isoformat_to_datetime(self.properties
 
149
                                                ["LastCheckedOK"])
 
150
        
 
151
        if self.properties ["LastCheckerStatus"] != 0:
 
152
            self.using_timer(True)
 
153
        
 
154
        if self.need_approval:
 
155
            self.using_timer(True)
 
156
        
146
157
        self.match_objects = (
147
158
            self.proxy.connect_to_signal("CheckerCompleted",
148
159
                                         self.checker_completed,
167
178
        #self.logger('Created client {0}'
168
179
        #            .format(self.properties["Name"]))
169
180
    
 
181
    def property_changed(self, property=None, value=None):
 
182
        super(self, MandosClientWidget).property_changed(property,
 
183
                                                         value)
 
184
        if property == "ApprovalPending":
 
185
            using_timer(bool(value))
 
186
        if property == "LastCheckerStatus":
 
187
            using_timer(value != 0)
 
188
            #self.logger('Checker for client {0} (command "{1}") was '
 
189
            #            ' successful'.format(self.properties["Name"],
 
190
            #                                 command))
 
191
    
170
192
    def using_timer(self, flag):
171
193
        """Call this method with True or False when timer should be
172
194
        activated or deactivated.
173
195
        """
174
 
        if flag and self._update_timer_callback_tag is None:
 
196
        old = self._update_timer_callback_lock
 
197
        if flag:
 
198
            self._update_timer_callback_lock += 1
 
199
        else:
 
200
            self._update_timer_callback_lock -= 1
 
201
        if old == 0 and self._update_timer_callback_lock:
175
202
            # Will update the shown timer value every second
176
203
            self._update_timer_callback_tag = (gobject.timeout_add
177
204
                                               (1000,
178
205
                                                self.update_timer))
179
 
        elif not (flag or self._update_timer_callback_tag is None):
 
206
        elif old and self._update_timer_callback_lock == 0:
180
207
            gobject.source_remove(self._update_timer_callback_tag)
181
208
            self._update_timer_callback_tag = None
182
209
    
224
251
            message = 'Client {0} will get its secret in {1} seconds'
225
252
        self.logger(message.format(self.properties["Name"],
226
253
                                   timeout/1000))
 
254
        self.using_timer(True)
227
255
    
228
256
    def rejected(self, reason):
229
257
        self.logger('Client {0} was rejected; reason: {1}'
255
283
                          "bold-underline-blink":
256
284
                              "bold-underline-blink-standout",
257
285
                          }
258
 
        
 
286
 
259
287
        # Rebuild focus and non-focus widgets using current properties
260
 
        
 
288
 
261
289
        # Base part of a client. Name!
262
290
        base = '{name}: '.format(name=self.properties["Name"])
263
291
        if not self.properties["Enabled"]:
264
292
            message = "DISABLED"
265
 
            self.using_timer(False)
266
293
        elif self.properties["ApprovalPending"]:
267
294
            timeout = datetime.timedelta(milliseconds
268
295
                                         = self.properties
270
297
            last_approval_request = isoformat_to_datetime(
271
298
                self.properties["LastApprovalRequest"])
272
299
            if last_approval_request is not None:
273
 
                timer = max(timeout - (datetime.datetime.utcnow()
274
 
                                       - last_approval_request),
275
 
                            datetime.timedelta())
 
300
                timer = timeout - (datetime.datetime.utcnow()
 
301
                                   - last_approval_request)
276
302
            else:
277
303
                timer = datetime.timedelta()
278
304
            if self.properties["ApprovedByDefault"]:
280
306
            else:
281
307
                message = "Denial in {0}. (a)pprove?"
282
308
            message = message.format(unicode(timer).rsplit(".", 1)[0])
283
 
            self.using_timer(True)
284
309
        elif self.properties["LastCheckerStatus"] != 0:
285
310
            # When checker has failed, show timer until client expires
286
311
            expires = self.properties["Expires"]
289
314
            else:
290
315
                expires = (datetime.datetime.strptime
291
316
                           (expires, '%Y-%m-%dT%H:%M:%S.%f'))
292
 
                timer = max(expires - datetime.datetime.utcnow(),
293
 
                            datetime.timedelta())
 
317
                timer = expires - datetime.datetime.utcnow()
294
318
            message = ('A checker has failed! Time until client'
295
319
                       ' gets disabled: {0}'
296
320
                       .format(unicode(timer).rsplit(".", 1)[0]))
297
 
            self.using_timer(True)
298
321
        else:
299
322
            message = "enabled"
300
 
            self.using_timer(False)
301
323
        self._text = "{0}{1}".format(base, message)
302
 
        
 
324
            
303
325
        if not urwid.supports_unicode():
304
326
            self._text = self._text.encode("ascii", "replace")
305
327
        textlist = [("normal", self._text)]
322
344
        self.update()
323
345
        return True             # Keep calling this
324
346
    
325
 
    def delete(self, **kwargs):
 
347
    def delete(self, *args, **kwargs):
326
348
        if self._update_timer_callback_tag is not None:
327
349
            gobject.source_remove(self._update_timer_callback_tag)
328
350
            self._update_timer_callback_tag = None
331
353
        self.match_objects = ()
332
354
        if self.delete_hook is not None:
333
355
            self.delete_hook(self)
334
 
        return super(MandosClientWidget, self).delete(**kwargs)
 
356
        return super(MandosClientWidget, self).delete(*args, **kwargs)
335
357
    
336
358
    def render(self, maxcolrow, focus=False):
337
359
        """Render differently if we have focus.
379
401
        else:
380
402
            return key
381
403
    
382
 
    def property_changed(self, property=None, **kwargs):
 
404
    def property_changed(self, property=None, value=None,
 
405
                         *args, **kwargs):
383
406
        """Call self.update() if old value is not new value.
384
407
        This overrides the method from MandosClientPropertyCache"""
385
408
        property_name = unicode(property)
386
409
        old_value = self.properties.get(property_name)
387
410
        super(MandosClientWidget, self).property_changed(
388
 
            property=property, **kwargs)
 
411
            property=property, value=value, *args, **kwargs)
389
412
        if self.properties.get(property_name) != old_value:
390
413
            self.update()
391
414
 
395
418
    "down" key presses, thus not allowing any containing widgets to
396
419
    use them as an excuse to shift focus away from this widget.
397
420
    """
398
 
    def keypress(self, *args, **kwargs):
399
 
        ret = super(ConstrainedListBox, self).keypress(*args, **kwargs)
 
421
    def keypress(self, maxcolrow, key):
 
422
        ret = super(ConstrainedListBox, self).keypress(maxcolrow, key)
400
423
        if ret in ("up", "down"):
401
424
            return
402
425
        return ret
617
640
                                               logger
618
641
                                               =self.log_message),
619
642
                            path=path)
620
 
        
 
643
 
621
644
        self.refresh()
622
645
        self._input_callback_tag = (gobject.io_add_watch
623
646
                                    (sys.stdin.fileno(),