/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

renamed some foomax values to what they actually represent
fixed a very small exitstatus bug in plugin-runner

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
# "AvahiService" class, and some lines in "main".
12
12
13
13
# Everything else is
14
 
# Copyright © 2008-2012 Teddy Hogeborn
15
 
# Copyright © 2008-2012 Björn Påhlsson
 
14
# Copyright © 2008-2011 Teddy Hogeborn
 
15
# Copyright © 2008-2011 Björn Påhlsson
16
16
17
17
# This program is free software: you can redistribute it and/or modify
18
18
# it under the terms of the GNU General Public License as published by
85
85
    except ImportError:
86
86
        SO_BINDTODEVICE = None
87
87
 
88
 
version = "1.5.1"
 
88
version = "1.4.1"
89
89
stored_state_file = "clients.pickle"
90
90
 
91
91
logger = logging.getLogger()
142
142
        self.gnupg.options.meta_interactive = False
143
143
        self.gnupg.options.homedir = self.tempdir
144
144
        self.gnupg.options.extra_args.extend(['--force-mdc',
145
 
                                              '--quiet',
146
 
                                              '--no-use-agent'])
 
145
                                              '--quiet'])
147
146
    
148
147
    def __enter__(self):
149
148
        return self
422
421
    secret:     bytestring; sent verbatim (over TLS) to client
423
422
    timeout:    datetime.timedelta(); How long from last_checked_ok
424
423
                                      until this client is disabled
425
 
    extended_timeout:   extra long timeout when secret has been sent
 
424
    extended_timeout:   extra long timeout when password has been sent
426
425
    runtime_expansions: Allowed attributes for runtime expansion.
427
426
    expires:    datetime.datetime(); time (UTC) when a client will be
428
427
                disabled, or None
460
459
 
461
460
    @staticmethod
462
461
    def config_parser(config):
463
 
        """Construct a new dict of client settings of this form:
 
462
        """ Construct a new dict of client settings of this form:
464
463
        { client_name: {setting_name: value, ...}, ...}
465
 
        with exceptions for any special settings as defined above.
466
 
        NOTE: Must be a pure function. Must return the same result
467
 
        value given the same arguments.
468
 
        """
 
464
        with exceptions for any special settings as defined above"""
469
465
        settings = {}
470
466
        for client_name in config.sections():
471
467
            section = dict(config.items(client_name))
475
471
            # Reformat values from string types to Python types
476
472
            client["approved_by_default"] = config.getboolean(
477
473
                client_name, "approved_by_default")
478
 
            client["enabled"] = config.getboolean(client_name,
479
 
                                                  "enabled")
 
474
            client["enabled"] = config.getboolean(client_name, "enabled")
480
475
            
481
476
            client["fingerprint"] = (section["fingerprint"].upper()
482
477
                                     .replace(" ", ""))
502
497
            client["last_approval_request"] = None
503
498
            client["last_checked_ok"] = None
504
499
            client["last_checker_status"] = None
505
 
        
 
500
            if client["enabled"]:
 
501
                client["last_enabled"] = datetime.datetime.utcnow()
 
502
                client["expires"] = (datetime.datetime.utcnow()
 
503
                                     + client["timeout"])
 
504
            else:
 
505
                client["last_enabled"] = None
 
506
                client["expires"] = None
 
507
 
506
508
        return settings
507
509
        
508
510
        
515
517
        for setting, value in settings.iteritems():
516
518
            setattr(self, setting, value)
517
519
        
518
 
        if self.enabled:
519
 
            if not hasattr(self, "last_enabled"):
520
 
                self.last_enabled = datetime.datetime.utcnow()
521
 
            if not hasattr(self, "expires"):
522
 
                self.expires = (datetime.datetime.utcnow()
523
 
                                + self.timeout)
524
 
        else:
525
 
            self.last_enabled = None
526
 
            self.expires = None
527
 
       
528
520
        logger.debug("Creating client %r", self.name)
529
521
        # Uppercase and remove spaces from fingerprint for later
530
522
        # comparison purposes with return value from the fingerprint()
531
523
        # function
532
524
        logger.debug("  Fingerprint: %s", self.fingerprint)
533
 
        self.created = settings.get("created",
534
 
                                    datetime.datetime.utcnow())
 
525
        self.created = settings.get("created", datetime.datetime.utcnow())
535
526
 
536
527
        # attributes specific for this server instance
537
528
        self.checker = None
850
841
            # signatures other than "ay".
851
842
            if prop._dbus_signature != "ay":
852
843
                raise ValueError
853
 
            value = dbus.ByteArray(b''.join(chr(byte)
854
 
                                            for byte in value))
 
844
            value = dbus.ByteArray(''.join(unichr(byte)
 
845
                                           for byte in value))
855
846
        prop(value)
856
847
    
857
848
    @dbus.service.method(dbus.PROPERTIES_IFACE, in_signature="s",
1049
1040
    def __init__(self, bus = None, *args, **kwargs):
1050
1041
        self.bus = bus
1051
1042
        Client.__init__(self, *args, **kwargs)
 
1043
        self._approvals_pending = 0
 
1044
        
 
1045
        self._approvals_pending = 0
1052
1046
        # Only now, when this client is initialized, can it show up on
1053
1047
        # the D-Bus
1054
1048
        client_object_name = unicode(self.name).translate(
1224
1218
        "D-Bus signal"
1225
1219
        return self.need_approval()
1226
1220
    
 
1221
    # NeRwequest - signal
 
1222
    @dbus.service.signal(_interface, signature="s")
 
1223
    def NewRequest(self, ip):
 
1224
        """D-Bus signal
 
1225
        Is sent after a client request a password.
 
1226
        """
 
1227
        pass
 
1228
    
1227
1229
    ## Methods
1228
1230
    
1229
1231
    # Approve - method
1356
1358
        if value is None:       # get
1357
1359
            return dbus.UInt64(self.timeout_milliseconds())
1358
1360
        self.timeout = datetime.timedelta(0, 0, 0, value)
 
1361
        if getattr(self, "disable_initiator_tag", None) is None:
 
1362
            return
1359
1363
        # Reschedule timeout
1360
 
        if self.enabled:
1361
 
            now = datetime.datetime.utcnow()
1362
 
            time_to_die = timedelta_to_milliseconds(
1363
 
                (self.last_checked_ok + self.timeout) - now)
1364
 
            if time_to_die <= 0:
1365
 
                # The timeout has passed
1366
 
                self.disable()
1367
 
            else:
1368
 
                self.expires = (now +
1369
 
                                datetime.timedelta(milliseconds =
1370
 
                                                   time_to_die))
1371
 
                if (getattr(self, "disable_initiator_tag", None)
1372
 
                    is None):
1373
 
                    return
1374
 
                gobject.source_remove(self.disable_initiator_tag)
1375
 
                self.disable_initiator_tag = (gobject.timeout_add
1376
 
                                              (time_to_die,
1377
 
                                               self.disable))
 
1364
        gobject.source_remove(self.disable_initiator_tag)
 
1365
        self.disable_initiator_tag = None
 
1366
        self.expires = None
 
1367
        time_to_die = timedelta_to_milliseconds((self
 
1368
                                                 .last_checked_ok
 
1369
                                                 + self.timeout)
 
1370
                                                - datetime.datetime
 
1371
                                                .utcnow())
 
1372
        if time_to_die <= 0:
 
1373
            # The timeout has passed
 
1374
            self.disable()
 
1375
        else:
 
1376
            self.expires = (datetime.datetime.utcnow()
 
1377
                            + datetime.timedelta(milliseconds =
 
1378
                                                 time_to_die))
 
1379
            self.disable_initiator_tag = (gobject.timeout_add
 
1380
                                          (time_to_die, self.disable))
1378
1381
    
1379
1382
    # ExtendedTimeout - property
1380
1383
    @dbus_service_property(_interface, signature="t",
1536
1539
                except KeyError:
1537
1540
                    return
1538
1541
                
 
1542
                if self.server.use_dbus:
 
1543
                    # Emit D-Bus signal
 
1544
                    client.NewRequest(str(self.client_address))
 
1545
                
1539
1546
                if client.approval_delay:
1540
1547
                    delay = client.approval_delay
1541
1548
                    client.approvals_pending += 1
2087
2094
                                % server_settings["servicename"]))
2088
2095
    
2089
2096
    # Parse config file with clients
2090
 
    client_config = configparser.SafeConfigParser(Client
2091
 
                                                  .client_defaults)
 
2097
    client_config = configparser.SafeConfigParser(Client.client_defaults)
2092
2098
    client_config.read(os.path.join(server_settings["configdir"],
2093
2099
                                    "clients.conf"))
2094
2100
    
2235
2241
            
2236
2242
            # Clients who has passed its expire date can still be
2237
2243
            # enabled if its last checker was successful.  Clients
2238
 
            # whose checker succeeded before we stored its state is
2239
 
            # assumed to have successfully run all checkers during
2240
 
            # downtime.
 
2244
            # whose checker failed before we stored its state is
 
2245
            # assumed to have failed all checkers during downtime.
2241
2246
            if client["enabled"]:
2242
2247
                if datetime.datetime.utcnow() >= client["expires"]:
2243
2248
                    if not client["last_checked_ok"]:
2244
2249
                        logger.warning(
2245
2250
                            "disabling client {0} - Client never "
2246
 
                            "performed a successful checker"
2247
 
                            .format(client_name))
 
2251
                            "performed a successfull checker"
 
2252
                            .format(client["name"]))
2248
2253
                        client["enabled"] = False
2249
2254
                    elif client["last_checker_status"] != 0:
2250
2255
                        logger.warning(
2251
2256
                            "disabling client {0} - Client "
2252
2257
                            "last checker failed with error code {1}"
2253
 
                            .format(client_name,
 
2258
                            .format(client["name"],
2254
2259
                                    client["last_checker_status"]))
2255
2260
                        client["enabled"] = False
2256
2261
                    else:
2257
2262
                        client["expires"] = (datetime.datetime
2258
2263
                                             .utcnow()
2259
2264
                                             + client["timeout"])
2260
 
                        logger.debug("Last checker succeeded,"
2261
 
                                     " keeping {0} enabled"
2262
 
                                     .format(client_name))
 
2265
                    
2263
2266
            try:
2264
2267
                client["secret"] = (
2265
2268
                    pgp.decrypt(client["encrypted_secret"],
2274
2277
 
2275
2278
    
2276
2279
    # Add/remove clients based on new changes made to config
2277
 
    for client_name in (set(old_client_settings)
2278
 
                        - set(client_settings)):
 
2280
    for client_name in set(old_client_settings) - set(client_settings):
2279
2281
        del clients_data[client_name]
2280
 
    for client_name in (set(client_settings)
2281
 
                        - set(old_client_settings)):
 
2282
    for client_name in set(client_settings) - set(old_client_settings):
2282
2283
        clients_data[client_name] = client_settings[client_name]
2283
2284
 
2284
 
    # Create all client objects
 
2285
    # Create clients all clients
2285
2286
    for client_name, client in clients_data.iteritems():
2286
2287
        tcp_server.clients[client_name] = client_class(
2287
2288
            name = client_name, settings = client)