/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

  • Committer: Teddy Hogeborn
  • Date: 2015-03-10 18:03:38 UTC
  • Revision ID: teddy@recompile.se-20150310180338-pcxw6r2qmw9k6br9
Add ":!RSA" to GnuTLS priority string, to disallow non-DHE kx.

If Mandos was somehow made to use a non-ephemeral Diffie-Hellman key
exchange algorithm in the TLS handshake, any saved network traffic
could then be decrypted later if the Mandos client key was obtained.
By default, Mandos uses ephemeral DH key exchanges which does not have
this problem, but a non-ephemeral key exchange algorithm was still
enabled by default.  The simplest solution is to simply turn that off,
which ensures that Mandos will always use ephemeral DH key exchanges.

There is a "PFS" priority string specifier, but we can't use it because:

1. Security-wise, it is a mix between "NORMAL" and "SECURE128" - it
   enables a lot more algorithms than "SECURE256".

2. It is only available since GnuTLS 3.2.4.

Thanks to Andreas Fischer <af@bantuX.org> for reporting this issue.

Show diffs side-by-side

added added

removed removed

Lines of Context:
91
91
if sys.version_info.major == 2:
92
92
    str = unicode
93
93
 
94
 
version = "1.6.8"
 
94
version = "1.6.9"
95
95
stored_state_file = "clients.pickle"
96
96
 
97
97
logger = logging.getLogger()
275
275
        self.bus = bus
276
276
        self.entry_group_state_changed_match = None
277
277
    
278
 
    def rename(self):
 
278
    def rename(self, remove=True):
279
279
        """Derived from the Avahi example code"""
280
280
        if self.rename_count >= self.max_renames:
281
281
            logger.critical("No suitable Zeroconf service name found"
284
284
            raise AvahiServiceError("Too many renames")
285
285
        self.name = str(self.server
286
286
                        .GetAlternativeServiceName(self.name))
 
287
        self.rename_count += 1
287
288
        logger.info("Changing Zeroconf service name to %r ...",
288
289
                    self.name)
289
 
        self.remove()
 
290
        if remove:
 
291
            self.remove()
290
292
        try:
291
293
            self.add()
292
294
        except dbus.exceptions.DBusException as error:
293
 
            logger.critical("D-Bus Exception", exc_info=error)
294
 
            self.cleanup()
295
 
            os._exit(1)
296
 
        self.rename_count += 1
 
295
            if (error.get_dbus_name()
 
296
                == "org.freedesktop.Avahi.CollisionError"):
 
297
                logger.info("Local Zeroconf service name collision.")
 
298
                return self.rename(remove=False)
 
299
            else:
 
300
                logger.critical("D-Bus Exception", exc_info=error)
 
301
                self.cleanup()
 
302
                os._exit(1)
297
303
    
298
304
    def remove(self):
299
305
        """Derived from the Avahi example code"""
391
397
 
392
398
 
393
399
class AvahiServiceToSyslog(AvahiService):
394
 
    def rename(self):
 
400
    def rename(self, *args, **kwargs):
395
401
        """Add the new name to the syslog messages"""
396
 
        ret = AvahiService.rename(self)
 
402
        ret = AvahiService.rename(self, *args, **kwargs)
397
403
        syslogger.setFormatter(logging.Formatter
398
404
                               ('Mandos ({}) [%(process)d]:'
399
405
                                ' %(levelname)s: %(message)s'
481
487
            client["enabled"] = config.getboolean(client_name,
482
488
                                                  "enabled")
483
489
            
 
490
            # Uppercase and remove spaces from fingerprint for later
 
491
            # comparison purposes with return value from the
 
492
            # fingerprint() function
484
493
            client["fingerprint"] = (section["fingerprint"].upper()
485
494
                                     .replace(" ", ""))
486
495
            if "secret" in section:
528
537
            self.expires = None
529
538
        
530
539
        logger.debug("Creating client %r", self.name)
531
 
        # Uppercase and remove spaces from fingerprint for later
532
 
        # comparison purposes with return value from the fingerprint()
533
 
        # function
534
540
        logger.debug("  Fingerprint: %s", self.fingerprint)
535
541
        self.created = settings.get("created",
536
542
                                    datetime.datetime.utcnow())
813
819
    """Decorator to annotate D-Bus methods, signals or properties
814
820
    Usage:
815
821
    
 
822
    @dbus_annotations({"org.freedesktop.DBus.Deprecated": "true",
 
823
                       "org.freedesktop.DBus.Property."
 
824
                       "EmitsChangedSignal": "false"})
816
825
    @dbus_service_property("org.example.Interface", signature="b",
817
826
                           access="r")
818
 
    @dbus_annotations({{"org.freedesktop.DBus.Deprecated": "true",
819
 
                        "org.freedesktop.DBus.Property."
820
 
                        "EmitsChangedSignal": "false"})
821
827
    def Property_dbus_property(self):
822
828
        return dbus.Boolean(False)
823
829
    """
946
952
                                           value.variant_level+1)
947
953
        return dbus.Dictionary(properties, signature="sv")
948
954
    
 
955
    @dbus.service.signal(dbus.PROPERTIES_IFACE, signature="sa{sv}as")
 
956
    def PropertiesChanged(self, interface_name, changed_properties,
 
957
                          invalidated_properties):
 
958
        """Standard D-Bus PropertiesChanged() signal, see D-Bus
 
959
        standard.
 
960
        """
 
961
        pass
 
962
    
949
963
    @dbus.service.method(dbus.INTROSPECTABLE_IFACE,
950
964
                         out_signature="s",
951
965
                         path_keyword='object_path',
1218
1232
    runtime_expansions = (Client.runtime_expansions
1219
1233
                          + ("dbus_object_path",))
1220
1234
    
 
1235
    _interface = "se.recompile.Mandos.Client"
 
1236
    
1221
1237
    # dbus.service.Object doesn't use super(), so we can't either.
1222
1238
    
1223
1239
    def __init__(self, bus = None, *args, **kwargs):
1235
1251
    
1236
1252
    def notifychangeproperty(transform_func,
1237
1253
                             dbus_name, type_func=lambda x: x,
1238
 
                             variant_level=1):
 
1254
                             variant_level=1, invalidate_only=False,
 
1255
                             _interface=_interface):
1239
1256
        """ Modify a variable so that it's a property which announces
1240
1257
        its changes to DBus.
1241
1258
        
1252
1269
                if (not hasattr(self, attrname) or
1253
1270
                    type_func(getattr(self, attrname, None))
1254
1271
                    != type_func(value)):
1255
 
                    dbus_value = transform_func(type_func(value),
1256
 
                                                variant_level
1257
 
                                                =variant_level)
1258
 
                    self.PropertyChanged(dbus.String(dbus_name),
1259
 
                                         dbus_value)
 
1272
                    if invalidate_only:
 
1273
                        self.PropertiesChanged(_interface,
 
1274
                                               dbus.Dictionary(),
 
1275
                                               dbus.Array
 
1276
                                               ((dbus_name,)))
 
1277
                    else:
 
1278
                        dbus_value = transform_func(type_func(value),
 
1279
                                                    variant_level
 
1280
                                                    =variant_level)
 
1281
                        self.PropertyChanged(dbus.String(dbus_name),
 
1282
                                             dbus_value)
 
1283
                        self.PropertiesChanged(_interface,
 
1284
                                               dbus.Dictionary({
 
1285
                                    dbus.String(dbus_name):
 
1286
                                        dbus_value }), dbus.Array())
1260
1287
            setattr(self, attrname, value)
1261
1288
        
1262
1289
        return property(lambda self: getattr(self, attrname), setter)
1300
1327
                                    lambda td: td.total_seconds()
1301
1328
                                    * 1000)
1302
1329
    checker_command = notifychangeproperty(dbus.String, "Checker")
 
1330
    secret = notifychangeproperty(dbus.ByteArray, "Secret",
 
1331
                                  invalidate_only=True)
1303
1332
    
1304
1333
    del notifychangeproperty
1305
1334
    
1352
1381
        self.send_changedstate()
1353
1382
    
1354
1383
    ## D-Bus methods, signals & properties
1355
 
    _interface = "se.recompile.Mandos.Client"
1356
1384
    
1357
1385
    ## Interfaces
1358
1386
    
1359
 
    @dbus_interface_annotations(_interface)
1360
 
    def _foo(self):
1361
 
        return { "org.freedesktop.DBus.Property.EmitsChangedSignal":
1362
 
                     "false"}
1363
 
    
1364
1387
    ## Signals
1365
1388
    
1366
1389
    # CheckerCompleted - signal
1376
1399
        pass
1377
1400
    
1378
1401
    # PropertyChanged - signal
 
1402
    @dbus_annotations({"org.freedesktop.DBus.Deprecated": "true"})
1379
1403
    @dbus.service.signal(_interface, signature="sv")
1380
1404
    def PropertyChanged(self, property, value):
1381
1405
        "D-Bus signal"
2332
2356
                        "port": "",
2333
2357
                        "debug": "False",
2334
2358
                        "priority":
2335
 
                        "SECURE256:!CTYPE-X.509:+CTYPE-OPENPGP:+SIGN-RSA-SHA224:+SIGN-RSA-RMD160",
 
2359
                        "SECURE256:!CTYPE-X.509:+CTYPE-OPENPGP:!RSA"
 
2360
                        ":+SIGN-RSA-SHA224:+SIGN-RSA-RMD160",
2336
2361
                        "servicename": "Mandos",
2337
2362
                        "use_dbus": "True",
2338
2363
                        "use_ipv6": "True",
2709
2734
            def GetAllClientsWithProperties(self):
2710
2735
                "D-Bus method"
2711
2736
                return dbus.Dictionary(
2712
 
                    ((c.dbus_object_path, c.GetAll(""))
2713
 
                     for c in tcp_server.clients.itervalues()),
 
2737
                    { c.dbus_object_path: c.GetAll("")
 
2738
                      for c in tcp_server.clients.itervalues() },
2714
2739
                    signature="oa{sv}")
2715
2740
            
2716
2741
            @dbus.service.method(_interface, in_signature="o")