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

  • Committer: Teddy Hogeborn
  • Date: 2011-12-31 20:07:11 UTC
  • mfrom: (535.1.9 wireless-network-hook)
  • Revision ID: teddy@recompile.se-20111231200711-6dli3r8drftem57r
Merge new wireless network hook.  Fix bridge network hook to use
hardware addresses instead of interface names.  Implement and document
new "CONNECT" environment variable for network hooks.

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 © 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
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
17
17
#     GNU General Public License for more details.
18
18
19
19
# You should have received a copy of the GNU General Public License
20
 
# along with this program.  If not, see
21
 
# <http://www.gnu.org/licenses/>.
 
20
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
22
21
23
22
# Contact the authors at <mandos@recompile.se>.
24
23
53
52
domain = 'se.recompile'
54
53
server_interface = domain + '.Mandos'
55
54
client_interface = domain + '.Mandos.Client'
56
 
version = "1.5.3"
 
55
version = "1.4.1"
57
56
 
58
57
# Always run in monochrome mode
59
58
urwid.curses_display.curses.has_colors = lambda : False
132
131
        
133
132
        self._update_timer_callback_tag = None
134
133
        self._update_timer_callback_lock = 0
 
134
        self.last_checker_failed = False
135
135
        
136
136
        # The widget shown normally
137
137
        self._text_widget = urwid.Text("")
145
145
        
146
146
        last_checked_ok = isoformat_to_datetime(self.properties
147
147
                                                ["LastCheckedOK"])
 
148
        if last_checked_ok is None:
 
149
            self.last_checker_failed = True
 
150
        else:
 
151
            self.last_checker_failed = ((datetime.datetime.utcnow()
 
152
                                         - last_checked_ok)
 
153
                                        > datetime.timedelta
 
154
                                        (milliseconds=
 
155
                                         self.properties
 
156
                                         ["Interval"]))
148
157
        
149
 
        if self.properties ["LastCheckerStatus"] != 0:
 
158
        if self.last_checker_failed:
150
159
            self.using_timer(True)
151
160
        
152
161
        if self.need_approval:
173
182
                                         self.rejected,
174
183
                                         client_interface,
175
184
                                         byte_arrays=True))
176
 
        #self.logger('Created client {0}'
177
 
        #            .format(self.properties["Name"]))
 
185
        #self.logger('Created client %s' % (self.properties["Name"]))
178
186
    
179
187
    def property_changed(self, property=None, value=None):
180
188
        super(self, MandosClientWidget).property_changed(property,
181
189
                                                         value)
182
190
        if property == "ApprovalPending":
183
191
            using_timer(bool(value))
184
 
        if property == "LastCheckerStatus":
185
 
            using_timer(value != 0)
186
 
            #self.logger('Checker for client {0} (command "{1}") was '
187
 
            #            ' successful'.format(self.properties["Name"],
188
 
            #                                 command))
189
 
    
 
192
        
190
193
    def using_timer(self, flag):
191
194
        """Call this method with True or False when timer should be
192
195
        activated or deactivated.
207
210
    
208
211
    def checker_completed(self, exitstatus, condition, command):
209
212
        if exitstatus == 0:
 
213
            if self.last_checker_failed:
 
214
                self.last_checker_failed = False
 
215
                self.using_timer(False)
 
216
            #self.logger('Checker for client %s (command "%s")'
 
217
            #            ' was successful'
 
218
            #            % (self.properties["Name"], command))
210
219
            self.update()
211
220
            return
212
221
        # Checker failed
 
222
        if not self.last_checker_failed:
 
223
            self.last_checker_failed = True
 
224
            self.using_timer(True)
213
225
        if os.WIFEXITED(condition):
214
 
            self.logger('Checker for client {0} (command "{1}")'
215
 
                        ' failed with exit code {2}'
216
 
                        .format(self.properties["Name"], command,
217
 
                                os.WEXITSTATUS(condition)))
 
226
            self.logger('Checker for client %s (command "%s")'
 
227
                        ' failed with exit code %s'
 
228
                        % (self.properties["Name"], command,
 
229
                           os.WEXITSTATUS(condition)))
218
230
        elif os.WIFSIGNALED(condition):
219
 
            self.logger('Checker for client {0} (command "{1}") was'
220
 
                        ' killed by signal {2}'
221
 
                        .format(self.properties["Name"], command,
222
 
                                os.WTERMSIG(condition)))
 
231
            self.logger('Checker for client %s (command "%s")'
 
232
                        ' was killed by signal %s'
 
233
                        % (self.properties["Name"], command,
 
234
                           os.WTERMSIG(condition)))
223
235
        elif os.WCOREDUMP(condition):
224
 
            self.logger('Checker for client {0} (command "{1}")'
 
236
            self.logger('Checker for client %s (command "%s")'
225
237
                        ' dumped core'
226
 
                        .format(self.properties["Name"], command))
 
238
                        % (self.properties["Name"], command))
227
239
        else:
228
 
            self.logger('Checker for client {0} completed'
229
 
                        ' mysteriously'
230
 
                        .format(self.properties["Name"]))
 
240
            self.logger('Checker for client %s completed'
 
241
                        ' mysteriously')
231
242
        self.update()
232
243
    
233
244
    def checker_started(self, command):
234
245
        """Server signals that a checker started. This could be useful
235
246
           to log in the future. """
236
 
        #self.logger('Client {0} started checker "{1}"'
237
 
        #            .format(self.properties["Name"],
238
 
        #                    unicode(command)))
 
247
        #self.logger('Client %s started checker "%s"'
 
248
        #            % (self.properties["Name"], unicode(command)))
239
249
        pass
240
250
    
241
251
    def got_secret(self):
242
 
        self.logger('Client {0} received its secret'
243
 
                    .format(self.properties["Name"]))
 
252
        self.last_checker_failed = False
 
253
        self.logger('Client %s received its secret'
 
254
                    % self.properties["Name"])
244
255
    
245
256
    def need_approval(self, timeout, default):
246
257
        if not default:
247
 
            message = 'Client {0} needs approval within {1} seconds'
 
258
            message = 'Client %s needs approval within %s seconds'
248
259
        else:
249
 
            message = 'Client {0} will get its secret in {1} seconds'
250
 
        self.logger(message.format(self.properties["Name"],
251
 
                                   timeout/1000))
 
260
            message = 'Client %s will get its secret in %s seconds'
 
261
        self.logger(message
 
262
                    % (self.properties["Name"], timeout/1000))
252
263
        self.using_timer(True)
253
264
    
254
265
    def rejected(self, reason):
255
 
        self.logger('Client {0} was rejected; reason: {1}'
256
 
                    .format(self.properties["Name"], reason))
 
266
        self.logger('Client %s was rejected; reason: %s'
 
267
                    % (self.properties["Name"], reason))
257
268
    
258
269
    def selectable(self):
259
270
        """Make this a "selectable" widget.
285
296
        # Rebuild focus and non-focus widgets using current properties
286
297
 
287
298
        # Base part of a client. Name!
288
 
        base = '{name}: '.format(name=self.properties["Name"])
 
299
        base = ('%(name)s: '
 
300
                      % {"name": self.properties["Name"]})
289
301
        if not self.properties["Enabled"]:
290
302
            message = "DISABLED"
291
303
        elif self.properties["ApprovalPending"]:
300
312
            else:
301
313
                timer = datetime.timedelta()
302
314
            if self.properties["ApprovedByDefault"]:
303
 
                message = "Approval in {0}. (d)eny?"
 
315
                message = "Approval in %s. (d)eny?"
304
316
            else:
305
 
                message = "Denial in {0}. (a)pprove?"
306
 
            message = message.format(unicode(timer).rsplit(".", 1)[0])
307
 
        elif self.properties["LastCheckerStatus"] != 0:
308
 
            # When checker has failed, show timer until client expires
 
317
                message = "Denial in %s. (a)pprove?"
 
318
            message = message % unicode(timer).rsplit(".", 1)[0]
 
319
        elif self.last_checker_failed:
 
320
            # When checker has failed, print a timer until client expires
309
321
            expires = self.properties["Expires"]
310
322
            if expires == "":
311
323
                timer = datetime.timedelta(0)
312
324
            else:
313
 
                expires = (datetime.datetime.strptime
314
 
                           (expires, '%Y-%m-%dT%H:%M:%S.%f'))
 
325
                expires = datetime.datetime.strptime(expires,
 
326
                                                     '%Y-%m-%dT%H:%M:%S.%f')
315
327
                timer = expires - datetime.datetime.utcnow()
316
328
            message = ('A checker has failed! Time until client'
317
 
                       ' gets disabled: {0}'
318
 
                       .format(unicode(timer).rsplit(".", 1)[0]))
 
329
                       ' gets disabled: %s'
 
330
                           % unicode(timer).rsplit(".", 1)[0])
319
331
        else:
320
332
            message = "enabled"
321
 
        self._text = "{0}{1}".format(base, message)
 
333
        self._text = "%s%s" % (base, message)
322
334
            
323
335
        if not urwid.supports_unicode():
324
336
            self._text = self._text.encode("ascii", "replace")
489
501
        self.main_loop = gobject.MainLoop()
490
502
    
491
503
    def client_not_found(self, fingerprint, address):
492
 
        self.log_message("Client with address {0} and fingerprint"
493
 
                         " {1} could not be found"
494
 
                         .format(address, fingerprint))
 
504
        self.log_message(("Client with address %s and fingerprint %s"
 
505
                          " could not be found" % (address,
 
506
                                                    fingerprint)))
495
507
    
496
508
    def rebuild(self):
497
509
        """This rebuilds the User Interface.
550
562
            client = self.clients_dict[path]
551
563
        except KeyError:
552
564
            # not found?
553
 
            self.log_message("Unknown client {0!r} ({1!r}) removed"
554
 
                             .format(name, path))
 
565
            self.log_message("Unknown client %r (%r) removed", name,
 
566
                             path)
555
567
            return
556
568
        client.delete()
557
569