/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-10-05 19:51:50 UTC
  • mfrom: (735 trunk)
  • mto: This revision was merged to the branch mainline in revision 736.
  • Revision ID: teddy@recompile.se-20141005195150-4amrg0janavtakyz
MergeĀ fromĀ trunk.

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