/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: 2014-07-25 23:54:03 UTC
  • Revision ID: teddy@recompile.se-20140725235403-8sx708g7rosge1ei
Bug fix to allow Python 3; that is, version 3 of the "python" package.

* debian/control (Package: mandos/Depends): Bug fix: Change from
                                            "python (<= 2.7)" to
                                            "python (>= 2.7)",
                                            allowing "/usr/bin/python"
                                            to be Python 3.

Show diffs side-by-side

added added

removed removed

Lines of Context:
88
88
    except ImportError:
89
89
        SO_BINDTODEVICE = None
90
90
 
91
 
if sys.version_info.major == 2:
92
 
    str = unicode
93
 
 
94
 
version = "1.6.8"
 
91
version = "1.6.7"
95
92
stored_state_file = "clients.pickle"
96
93
 
97
94
logger = logging.getLogger()
107
104
        SIOCGIFINDEX = 0x8933  # From /usr/include/linux/sockios.h
108
105
        with contextlib.closing(socket.socket()) as s:
109
106
            ifreq = fcntl.ioctl(s, SIOCGIFINDEX,
110
 
                                struct.pack(b"16s16x", interface))
111
 
        interface_index = struct.unpack("I", ifreq[16:20])[0]
 
107
                                struct.pack(str("16s16x"),
 
108
                                            interface))
 
109
        interface_index = struct.unpack(str("I"),
 
110
                                        ifreq[16:20])[0]
112
111
        return interface_index
113
112
 
114
113
 
119
118
    syslogger = (logging.handlers.SysLogHandler
120
119
                 (facility =
121
120
                  logging.handlers.SysLogHandler.LOG_DAEMON,
122
 
                  address = "/dev/log"))
 
121
                  address = str("/dev/log")))
123
122
    syslogger.setFormatter(logging.Formatter
124
123
                           ('Mandos [%(process)d]: %(levelname)s:'
125
124
                            ' %(message)s'))
225
224
class AvahiError(Exception):
226
225
    def __init__(self, value, *args, **kwargs):
227
226
        self.value = value
228
 
        return super(AvahiError, self).__init__(value, *args,
229
 
                                                **kwargs)
 
227
        super(AvahiError, self).__init__(value, *args, **kwargs)
 
228
    def __unicode__(self):
 
229
        return unicode(repr(self.value))
230
230
 
231
231
class AvahiServiceError(AvahiError):
232
232
    pass
282
282
                            " after %i retries, exiting.",
283
283
                            self.rename_count)
284
284
            raise AvahiServiceError("Too many renames")
285
 
        self.name = str(self.server
286
 
                        .GetAlternativeServiceName(self.name))
 
285
        self.name = unicode(self.server
 
286
                            .GetAlternativeServiceName(self.name))
287
287
        logger.info("Changing Zeroconf service name to %r ...",
288
288
                    self.name)
289
289
        self.remove()
337
337
            self.rename()
338
338
        elif state == avahi.ENTRY_GROUP_FAILURE:
339
339
            logger.critical("Avahi: Error in group state changed %s",
340
 
                            str(error))
 
340
                            unicode(error))
341
341
            raise AvahiGroupError("State changed: {!s}"
342
342
                                  .format(error))
343
343
    
688
688
        if self.checker is None:
689
689
            # Escape attributes for the shell
690
690
            escaped_attrs = { attr:
691
 
                                  re.escape(str(getattr(self, attr)))
 
691
                                  re.escape(unicode(getattr(self,
 
692
                                                            attr)))
692
693
                              for attr in self.runtime_expansions }
693
694
            try:
694
695
                command = self.checker_command % escaped_attrs
813
814
    """Decorator to annotate D-Bus methods, signals or properties
814
815
    Usage:
815
816
    
816
 
    @dbus_annotations({"org.freedesktop.DBus.Deprecated": "true",
817
 
                       "org.freedesktop.DBus.Property."
818
 
                       "EmitsChangedSignal": "false"})
819
817
    @dbus_service_property("org.example.Interface", signature="b",
820
818
                           access="r")
 
819
    @dbus_annotations({{"org.freedesktop.DBus.Deprecated": "true",
 
820
                        "org.freedesktop.DBus.Property."
 
821
                        "EmitsChangedSignal": "false"})
821
822
    def Property_dbus_property(self):
822
823
        return dbus.Boolean(False)
823
824
    """
830
831
class DBusPropertyException(dbus.exceptions.DBusException):
831
832
    """A base class for D-Bus property-related exceptions
832
833
    """
833
 
    pass
 
834
    def __unicode__(self):
 
835
        return unicode(str(self))
 
836
 
834
837
 
835
838
class DBusPropertyAccessException(DBusPropertyException):
836
839
    """A property's access permissions disallows an operation.
946
949
                                           value.variant_level+1)
947
950
        return dbus.Dictionary(properties, signature="sv")
948
951
    
949
 
    @dbus.service.signal(dbus.PROPERTIES_IFACE, signature="sa{sv}as")
950
 
    def PropertiesChanged(self, interface_name, changed_properties,
951
 
                          invalidated_properties):
952
 
        """Standard D-Bus PropertiesChanged() signal, see D-Bus
953
 
        standard.
954
 
        """
955
 
        pass
956
 
    
957
952
    @dbus.service.method(dbus.INTROSPECTABLE_IFACE,
958
953
                         out_signature="s",
959
954
                         path_keyword='object_path',
1226
1221
    runtime_expansions = (Client.runtime_expansions
1227
1222
                          + ("dbus_object_path",))
1228
1223
    
1229
 
    _interface = "se.recompile.Mandos.Client"
1230
 
    
1231
1224
    # dbus.service.Object doesn't use super(), so we can't either.
1232
1225
    
1233
1226
    def __init__(self, bus = None, *args, **kwargs):
1235
1228
        Client.__init__(self, *args, **kwargs)
1236
1229
        # Only now, when this client is initialized, can it show up on
1237
1230
        # the D-Bus
1238
 
        client_object_name = str(self.name).translate(
 
1231
        client_object_name = unicode(self.name).translate(
1239
1232
            {ord("."): ord("_"),
1240
1233
             ord("-"): ord("_")})
1241
1234
        self.dbus_object_path = (dbus.ObjectPath
1245
1238
    
1246
1239
    def notifychangeproperty(transform_func,
1247
1240
                             dbus_name, type_func=lambda x: x,
1248
 
                             variant_level=1, invalidate_only=False,
1249
 
                             _interface=_interface):
 
1241
                             variant_level=1):
1250
1242
        """ Modify a variable so that it's a property which announces
1251
1243
        its changes to DBus.
1252
1244
        
1263
1255
                if (not hasattr(self, attrname) or
1264
1256
                    type_func(getattr(self, attrname, None))
1265
1257
                    != type_func(value)):
1266
 
                    if invalidate_only:
1267
 
                        self.PropertiesChanged(_interface,
1268
 
                                               dbus.Dictionary(),
1269
 
                                               dbus.Array
1270
 
                                               ((dbus_name,)))
1271
 
                    else:
1272
 
                        dbus_value = transform_func(type_func(value),
1273
 
                                                    variant_level
1274
 
                                                    =variant_level)
1275
 
                        self.PropertyChanged(dbus.String(dbus_name),
1276
 
                                             dbus_value)
1277
 
                        self.PropertiesChanged(_interface,
1278
 
                                               dbus.Dictionary({
1279
 
                                    dbus.String(dbus_name):
1280
 
                                        dbus_value }), dbus.Array())
 
1258
                    dbus_value = transform_func(type_func(value),
 
1259
                                                variant_level
 
1260
                                                =variant_level)
 
1261
                    self.PropertyChanged(dbus.String(dbus_name),
 
1262
                                         dbus_value)
1281
1263
            setattr(self, attrname, value)
1282
1264
        
1283
1265
        return property(lambda self: getattr(self, attrname), setter)
1321
1303
                                    lambda td: td.total_seconds()
1322
1304
                                    * 1000)
1323
1305
    checker_command = notifychangeproperty(dbus.String, "Checker")
1324
 
    secret = notifychangeproperty(dbus.ByteArray, "Secret",
1325
 
                                  invalidate_only=True)
1326
1306
    
1327
1307
    del notifychangeproperty
1328
1308
    
1375
1355
        self.send_changedstate()
1376
1356
    
1377
1357
    ## D-Bus methods, signals & properties
 
1358
    _interface = "se.recompile.Mandos.Client"
1378
1359
    
1379
1360
    ## Interfaces
1380
1361
    
 
1362
    @dbus_interface_annotations(_interface)
 
1363
    def _foo(self):
 
1364
        return { "org.freedesktop.DBus.Property.EmitsChangedSignal":
 
1365
                     "false"}
 
1366
    
1381
1367
    ## Signals
1382
1368
    
1383
1369
    # CheckerCompleted - signal
1393
1379
        pass
1394
1380
    
1395
1381
    # PropertyChanged - signal
1396
 
    @dbus_annotations({"org.freedesktop.DBus.Deprecated": "true"})
1397
1382
    @dbus.service.signal(_interface, signature="sv")
1398
1383
    def PropertyChanged(self, property, value):
1399
1384
        "D-Bus signal"
1504
1489
    def Host_dbus_property(self, value=None):
1505
1490
        if value is None:       # get
1506
1491
            return dbus.String(self.host)
1507
 
        self.host = str(value)
 
1492
        self.host = unicode(value)
1508
1493
    
1509
1494
    # Created - property
1510
1495
    @dbus_service_property(_interface, signature="s", access="read")
1608
1593
    def Checker_dbus_property(self, value=None):
1609
1594
        if value is None:       # get
1610
1595
            return dbus.String(self.checker_command)
1611
 
        self.checker_command = str(value)
 
1596
        self.checker_command = unicode(value)
1612
1597
    
1613
1598
    # CheckerRunning - property
1614
1599
    @dbus_service_property(_interface, signature="b",
1630
1615
    @dbus_service_property(_interface, signature="ay",
1631
1616
                           access="write", byte_arrays=True)
1632
1617
    def Secret_dbus_property(self, value):
1633
 
        self.secret = bytes(value)
 
1618
        self.secret = str(value)
1634
1619
    
1635
1620
    del _interface
1636
1621
 
1670
1655
    def handle(self):
1671
1656
        with contextlib.closing(self.server.child_pipe) as child_pipe:
1672
1657
            logger.info("TCP connection from: %s",
1673
 
                        str(self.client_address))
 
1658
                        unicode(self.client_address))
1674
1659
            logger.debug("Pipe FD: %d",
1675
1660
                         self.server.child_pipe.fileno())
1676
1661
            
1975
1960
                try:
1976
1961
                    self.socket.setsockopt(socket.SOL_SOCKET,
1977
1962
                                           SO_BINDTODEVICE,
1978
 
                                           (self.interface + "\0")
1979
 
                                           .encode("utf-8"))
 
1963
                                           str(self.interface + '\0'))
1980
1964
                except socket.error as error:
1981
1965
                    if error.errno == errno.EPERM:
1982
1966
                        logger.error("No permission to bind to"
2242
2226
    timevalue = datetime.timedelta(0)
2243
2227
    for s in interval.split():
2244
2228
        try:
2245
 
            suffix = s[-1]
 
2229
            suffix = unicode(s[-1])
2246
2230
            value = int(s[:-1])
2247
2231
            if suffix == "d":
2248
2232
                delta = datetime.timedelta(value)
2399
2383
    del options
2400
2384
    # Force all strings to be unicode
2401
2385
    for option in server_settings.keys():
2402
 
        if isinstance(server_settings[option], bytes):
2403
 
            server_settings[option] = (server_settings[option]
2404
 
                                       .decode("utf-8"))
 
2386
        if type(server_settings[option]) is str:
 
2387
            server_settings[option] = unicode(server_settings[option])
2405
2388
    # Force all boolean options to be boolean
2406
2389
    for option in ("debug", "use_dbus", "use_ipv6", "restore",
2407
2390
                   "foreground", "zeroconf"):
2550
2533
                                       protocol = protocol, bus = bus)
2551
2534
        if server_settings["interface"]:
2552
2535
            service.interface = (if_nametoindex
2553
 
                                 (server_settings["interface"]
2554
 
                                  .encode("utf-8")))
 
2536
                                 (str(server_settings["interface"])))
2555
2537
    
2556
2538
    global multiprocessing_manager
2557
2539
    multiprocessing_manager = multiprocessing.Manager()
2675
2657
            try:
2676
2658
                with pidfile:
2677
2659
                    pid = os.getpid()
2678
 
                    pidfile.write("{}\n".format(pid).encode("utf-8"))
 
2660
                    pidfile.write(str(pid) + "\n".encode("utf-8"))
2679
2661
            except IOError:
2680
2662
                logger.error("Could not write to file %r with PID %d",
2681
2663
                             pidfilename, pid)
2727
2709
            def GetAllClientsWithProperties(self):
2728
2710
                "D-Bus method"
2729
2711
                return dbus.Dictionary(
2730
 
                    { c.dbus_object_path: c.GetAll("")
2731
 
                      for c in tcp_server.clients.itervalues() },
 
2712
                    ((c.dbus_object_path, c.GetAll(""))
 
2713
                     for c in tcp_server.clients.itervalues()),
2732
2714
                    signature="oa{sv}")
2733
2715
            
2734
2716
            @dbus.service.method(_interface, in_signature="o")