/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

* mandos (ClientDBus.notifychangeproperty): Bug fix: Use instance
                                            attributes instead of
                                            class attributes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
28
28
# along with this program.  If not, see
29
29
# <http://www.gnu.org/licenses/>.
30
30
31
 
# Contact the authors at <mandos@fukt.bsnet.se>.
 
31
# Contact the authors at <mandos@recompile.se>.
32
32
33
33
 
34
34
from __future__ import (division, absolute_import, print_function,
62
62
import functools
63
63
import cPickle as pickle
64
64
import multiprocessing
 
65
import types
65
66
 
66
67
import dbus
67
68
import dbus.service
159
160
                            " after %i retries, exiting.",
160
161
                            self.rename_count)
161
162
            raise AvahiServiceError("Too many renames")
162
 
        self.name = unicode(self.server.GetAlternativeServiceName(self.name))
 
163
        self.name = unicode(self.server
 
164
                            .GetAlternativeServiceName(self.name))
163
165
        logger.info("Changing Zeroconf service name to %r ...",
164
166
                    self.name)
165
167
        syslogger.setFormatter(logging.Formatter
313
315
                          "created", "enabled", "fingerprint",
314
316
                          "host", "interval", "last_checked_ok",
315
317
                          "last_enabled", "name", "timeout")
316
 
        
 
318
    
317
319
    def timeout_milliseconds(self):
318
320
        "Return the 'timeout' attribute in milliseconds"
319
321
        return _timedelta_to_milliseconds(self.timeout)
320
 
 
 
322
    
321
323
    def extended_timeout_milliseconds(self):
322
324
        "Return the 'extended_timeout' attribute in milliseconds"
323
 
        return _timedelta_to_milliseconds(self.extended_timeout)    
 
325
        return _timedelta_to_milliseconds(self.extended_timeout)
324
326
    
325
327
    def interval_milliseconds(self):
326
328
        "Return the 'interval' attribute in milliseconds"
327
329
        return _timedelta_to_milliseconds(self.interval)
328
 
 
 
330
    
329
331
    def approval_delay_milliseconds(self):
330
332
        return _timedelta_to_milliseconds(self.approval_delay)
331
333
    
360
362
        self.last_enabled = None
361
363
        self.last_checked_ok = None
362
364
        self.timeout = string_to_delta(config["timeout"])
363
 
        self.extended_timeout = string_to_delta(config["extended_timeout"])
 
365
        self.extended_timeout = string_to_delta(config
 
366
                                                ["extended_timeout"])
364
367
        self.interval = string_to_delta(config["interval"])
365
368
        self.disable_hook = disable_hook
366
369
        self.checker = None
379
382
            config["approval_delay"])
380
383
        self.approval_duration = string_to_delta(
381
384
            config["approval_duration"])
382
 
        self.changedstate = multiprocessing_manager.Condition(multiprocessing_manager.Lock())
 
385
        self.changedstate = (multiprocessing_manager
 
386
                             .Condition(multiprocessing_manager
 
387
                                        .Lock()))
383
388
    
384
389
    def send_changedstate(self):
385
390
        self.changedstate.acquire()
386
391
        self.changedstate.notify_all()
387
392
        self.changedstate.release()
388
 
        
 
393
    
389
394
    def enable(self):
390
395
        """Start this client's checker and timeout hooks"""
391
396
        if getattr(self, "enabled", False):
462
467
        gobject.source_remove(self.disable_initiator_tag)
463
468
        self.expires = datetime.datetime.utcnow() + timeout
464
469
        self.disable_initiator_tag = (gobject.timeout_add
465
 
                                      (_timedelta_to_milliseconds(timeout),
466
 
                                       self.disable))
 
470
                                      (_timedelta_to_milliseconds
 
471
                                       (timeout), self.disable))
467
472
    
468
473
    def need_approval(self):
469
474
        self.last_approval_request = datetime.datetime.utcnow()
509
514
                                       'replace')))
510
515
                    for attr in
511
516
                    self.runtime_expansions)
512
 
 
 
517
                
513
518
                try:
514
519
                    command = self.checker_command % escaped_attrs
515
520
                except TypeError as error:
561
566
                raise
562
567
        self.checker = None
563
568
 
 
569
 
564
570
def dbus_service_property(dbus_interface, signature="v",
565
571
                          access="readwrite", byte_arrays=False):
566
572
    """Decorators for marking methods of a DBusObjectWithProperties to
612
618
 
613
619
class DBusObjectWithProperties(dbus.service.Object):
614
620
    """A D-Bus object with properties.
615
 
 
 
621
    
616
622
    Classes inheriting from this can use the dbus_service_property
617
623
    decorator to expose methods as D-Bus properties.  It exposes the
618
624
    standard Get(), Set(), and GetAll() methods on the D-Bus.
625
631
    def _get_all_dbus_properties(self):
626
632
        """Returns a generator of (name, attribute) pairs
627
633
        """
628
 
        return ((prop._dbus_name, prop)
 
634
        return ((prop.__get__(self)._dbus_name, prop.__get__(self))
 
635
                for cls in self.__class__.__mro__
629
636
                for name, prop in
630
 
                inspect.getmembers(self, self._is_dbus_property))
 
637
                inspect.getmembers(cls, self._is_dbus_property))
631
638
    
632
639
    def _get_dbus_property(self, interface_name, property_name):
633
640
        """Returns a bound method if one exists which is a D-Bus
634
641
        property with the specified name and interface.
635
642
        """
636
 
        for name in (property_name,
637
 
                     property_name + "_dbus_property"):
638
 
            prop = getattr(self, name, None)
639
 
            if (prop is None
640
 
                or not self._is_dbus_property(prop)
641
 
                or prop._dbus_name != property_name
642
 
                or (interface_name and prop._dbus_interface
643
 
                    and interface_name != prop._dbus_interface)):
644
 
                continue
645
 
            return prop
 
643
        for cls in  self.__class__.__mro__:
 
644
            for name, value in (inspect.getmembers
 
645
                                (cls, self._is_dbus_property)):
 
646
                if (value._dbus_name == property_name
 
647
                    and value._dbus_interface == interface_name):
 
648
                    return value.__get__(self)
 
649
        
646
650
        # No such property
647
651
        raise DBusPropertyNotFound(self.dbus_object_path + ":"
648
652
                                   + interface_name + "."
682
686
    def GetAll(self, interface_name):
683
687
        """Standard D-Bus property GetAll() method, see D-Bus
684
688
        standard.
685
 
 
 
689
        
686
690
        Note: Will not include properties with access="write".
687
691
        """
688
692
        all = {}
757
761
    return dbus.String(dt.isoformat(),
758
762
                       variant_level=variant_level)
759
763
 
 
764
class AlternateDBusNamesMetaclass(DBusObjectWithProperties
 
765
                                  .__metaclass__):
 
766
    """Applied to an empty subclass of a D-Bus object, this metaclass
 
767
    will add additional D-Bus attributes matching a certain pattern.
 
768
    """
 
769
    def __new__(mcs, name, bases, attr):
 
770
        # Go through all the base classes which could have D-Bus
 
771
        # methods, signals, or properties in them
 
772
        for base in (b for b in bases
 
773
                     if issubclass(b, dbus.service.Object)):
 
774
            # Go though all attributes of the base class
 
775
            for attrname, attribute in inspect.getmembers(base):
 
776
                # Ignore non-D-Bus attributes, and D-Bus attributes
 
777
                # with the wrong interface name
 
778
                if (not hasattr(attribute, "_dbus_interface")
 
779
                    or not attribute._dbus_interface
 
780
                    .startswith("se.recompile.Mandos")):
 
781
                    continue
 
782
                # Create an alternate D-Bus interface name based on
 
783
                # the current name
 
784
                alt_interface = (attribute._dbus_interface
 
785
                                 .replace("se.recompile.Mandos",
 
786
                                          "se.bsnet.fukt.Mandos"))
 
787
                # Is this a D-Bus signal?
 
788
                if getattr(attribute, "_dbus_is_signal", False):
 
789
                    # Extract the original non-method function by
 
790
                    # black magic
 
791
                    nonmethod_func = (dict(
 
792
                            zip(attribute.func_code.co_freevars,
 
793
                                attribute.__closure__))["func"]
 
794
                                      .cell_contents)
 
795
                    # Create a new, but exactly alike, function
 
796
                    # object, and decorate it to be a new D-Bus signal
 
797
                    # with the alternate D-Bus interface name
 
798
                    new_function = (dbus.service.signal
 
799
                                    (alt_interface,
 
800
                                     attribute._dbus_signature)
 
801
                                    (types.FunctionType(
 
802
                                nonmethod_func.func_code,
 
803
                                nonmethod_func.func_globals,
 
804
                                nonmethod_func.func_name,
 
805
                                nonmethod_func.func_defaults,
 
806
                                nonmethod_func.func_closure)))
 
807
                    # Define a creator of a function to call both the
 
808
                    # old and new functions, so both the old and new
 
809
                    # signals gets sent when the function is called
 
810
                    def fixscope(func1, func2):
 
811
                        """This function is a scope container to pass
 
812
                        func1 and func2 to the "call_both" function
 
813
                        outside of its arguments"""
 
814
                        def call_both(*args, **kwargs):
 
815
                            """This function will emit two D-Bus
 
816
                            signals by calling func1 and func2"""
 
817
                            func1(*args, **kwargs)
 
818
                            func2(*args, **kwargs)
 
819
                        return call_both
 
820
                    # Create the "call_both" function and add it to
 
821
                    # the class
 
822
                    attr[attrname] = fixscope(attribute,
 
823
                                              new_function)
 
824
                # Is this a D-Bus method?
 
825
                elif getattr(attribute, "_dbus_is_method", False):
 
826
                    # Create a new, but exactly alike, function
 
827
                    # object.  Decorate it to be a new D-Bus method
 
828
                    # with the alternate D-Bus interface name.  Add it
 
829
                    # to the class.
 
830
                    attr[attrname] = (dbus.service.method
 
831
                                      (alt_interface,
 
832
                                       attribute._dbus_in_signature,
 
833
                                       attribute._dbus_out_signature)
 
834
                                      (types.FunctionType
 
835
                                       (attribute.func_code,
 
836
                                        attribute.func_globals,
 
837
                                        attribute.func_name,
 
838
                                        attribute.func_defaults,
 
839
                                        attribute.func_closure)))
 
840
                # Is this a D-Bus property?
 
841
                elif getattr(attribute, "_dbus_is_property", False):
 
842
                    # Create a new, but exactly alike, function
 
843
                    # object, and decorate it to be a new D-Bus
 
844
                    # property with the alternate D-Bus interface
 
845
                    # name.  Add it to the class.
 
846
                    attr[attrname] = (dbus_service_property
 
847
                                      (alt_interface,
 
848
                                       attribute._dbus_signature,
 
849
                                       attribute._dbus_access,
 
850
                                       attribute
 
851
                                       ._dbus_get_args_options
 
852
                                       ["byte_arrays"])
 
853
                                      (types.FunctionType
 
854
                                       (attribute.func_code,
 
855
                                        attribute.func_globals,
 
856
                                        attribute.func_name,
 
857
                                        attribute.func_defaults,
 
858
                                        attribute.func_closure)))
 
859
        return type.__new__(mcs, name, bases, attr)
 
860
 
760
861
class ClientDBus(Client, DBusObjectWithProperties):
761
862
    """A Client class using D-Bus
762
863
    
787
888
    def notifychangeproperty(transform_func,
788
889
                             dbus_name, type_func=lambda x: x,
789
890
                             variant_level=1):
790
 
        """ Modify a variable so that its a property that announce its
791
 
        changes to DBus.
792
 
        transform_fun: Function that takes a value and transform it to
793
 
                       DBus type.
794
 
        dbus_name: DBus name of the variable
 
891
        """ Modify a variable so that it's a property which announces
 
892
        its changes to DBus.
 
893
 
 
894
        transform_fun: Function that takes a value and transforms it
 
895
                       to a D-Bus type.
 
896
        dbus_name: D-Bus name of the variable
795
897
        type_func: Function that transform the value before sending it
796
 
                   to DBus
797
 
        variant_level: DBus variant level. default: 1
 
898
                   to the D-Bus.  Default: no transform
 
899
        variant_level: D-Bus variant level.  Default: 1
798
900
        """
799
 
        real_value = [None,]
 
901
        attrname = "_{0}".format(dbus_name)
800
902
        def setter(self, value):
801
 
            old_value = real_value[0]
802
 
            real_value[0] = value
803
903
            if hasattr(self, "dbus_object_path"):
804
 
                if type_func(old_value) != type_func(real_value[0]):
805
 
                    dbus_value = transform_func(type_func(real_value[0]),
 
904
                if (not hasattr(self, attrname) or
 
905
                    type_func(getattr(self, attrname, None))
 
906
                    != type_func(value)):
 
907
                    dbus_value = transform_func(type_func(value),
806
908
                                                variant_level)
807
909
                    self.PropertyChanged(dbus.String(dbus_name),
808
910
                                         dbus_value)
809
 
 
810
 
        return property(lambda self: real_value[0], setter)
811
 
 
812
 
 
 
911
            setattr(self, attrname, value)
 
912
        
 
913
        return property(lambda self: getattr(self, attrname), setter)
 
914
    
 
915
    
813
916
    expires = notifychangeproperty(datetime_to_dbus, "Expires")
814
917
    approvals_pending = notifychangeproperty(dbus.Boolean,
815
918
                                             "ApprovalPending",
818
921
    last_enabled = notifychangeproperty(datetime_to_dbus,
819
922
                                        "LastEnabled")
820
923
    checker = notifychangeproperty(dbus.Boolean, "CheckerRunning",
821
 
                                   type_func = lambda checker: checker is not None)
 
924
                                   type_func = lambda checker:
 
925
                                       checker is not None)
822
926
    last_checked_ok = notifychangeproperty(datetime_to_dbus,
823
927
                                           "LastCheckedOK")
824
 
    last_approval_request = notifychangeproperty(datetime_to_dbus,
825
 
                                                 "LastApprovalRequest")
 
928
    last_approval_request = notifychangeproperty(
 
929
        datetime_to_dbus, "LastApprovalRequest")
826
930
    approved_by_default = notifychangeproperty(dbus.Boolean,
827
931
                                               "ApprovedByDefault")
828
 
    approval_delay = notifychangeproperty(dbus.UInt16, "ApprovalDelay",
829
 
                                          type_func = _timedelta_to_milliseconds)
830
 
    approval_duration = notifychangeproperty(dbus.UInt16, "ApprovalDuration",
831
 
                                             type_func = _timedelta_to_milliseconds)
 
932
    approval_delay = notifychangeproperty(dbus.UInt16,
 
933
                                          "ApprovalDelay",
 
934
                                          type_func =
 
935
                                          _timedelta_to_milliseconds)
 
936
    approval_duration = notifychangeproperty(
 
937
        dbus.UInt16, "ApprovalDuration",
 
938
        type_func = _timedelta_to_milliseconds)
832
939
    host = notifychangeproperty(dbus.String, "Host")
833
940
    timeout = notifychangeproperty(dbus.UInt16, "Timeout",
834
 
                                   type_func = _timedelta_to_milliseconds)
835
 
    extended_timeout = notifychangeproperty(dbus.UInt16, "ExtendedTimeout",
836
 
                                            type_func = _timedelta_to_milliseconds)
837
 
    interval = notifychangeproperty(dbus.UInt16, "Interval",
838
 
                                    type_func = _timedelta_to_milliseconds)
 
941
                                   type_func =
 
942
                                   _timedelta_to_milliseconds)
 
943
    extended_timeout = notifychangeproperty(
 
944
        dbus.UInt16, "ExtendedTimeout",
 
945
        type_func = _timedelta_to_milliseconds)
 
946
    interval = notifychangeproperty(dbus.UInt16,
 
947
                                    "Interval",
 
948
                                    type_func =
 
949
                                    _timedelta_to_milliseconds)
839
950
    checker_command = notifychangeproperty(dbus.String, "Checker")
840
951
    
841
952
    del notifychangeproperty
867
978
        
868
979
        return Client.checker_callback(self, pid, condition, command,
869
980
                                       *args, **kwargs)
870
 
 
 
981
    
871
982
    def start_checker(self, *args, **kwargs):
872
983
        old_checker = self.checker
873
984
        if self.checker is not None:
895
1006
    
896
1007
    
897
1008
    ## D-Bus methods, signals & properties
898
 
    _interface = "se.bsnet.fukt.Mandos.Client"
 
1009
    _interface = "se.recompile.Mandos.Client"
899
1010
    
900
1011
    ## Signals
901
1012
    
1087
1198
            self.disable()
1088
1199
        else:
1089
1200
            self.expires = (datetime.datetime.utcnow()
1090
 
                            + datetime.timedelta(milliseconds = time_to_die))
 
1201
                            + datetime.timedelta(milliseconds =
 
1202
                                                 time_to_die))
1091
1203
            self.disable_initiator_tag = (gobject.timeout_add
1092
1204
                                          (time_to_die, self.disable))
1093
 
 
 
1205
    
1094
1206
    # ExtendedTimeout - property
1095
1207
    @dbus_service_property(_interface, signature="t",
1096
1208
                           access="readwrite")
1098
1210
        if value is None:       # get
1099
1211
            return dbus.UInt64(self.extended_timeout_milliseconds())
1100
1212
        self.extended_timeout = datetime.timedelta(0, 0, 0, value)
1101
 
 
 
1213
    
1102
1214
    # Interval - property
1103
1215
    @dbus_service_property(_interface, signature="t",
1104
1216
                           access="readwrite")
1113
1225
        self.checker_initiator_tag = (gobject.timeout_add
1114
1226
                                      (value, self.start_checker))
1115
1227
        self.start_checker()    # Start one now, too
1116
 
 
 
1228
    
1117
1229
    # Checker - property
1118
1230
    @dbus_service_property(_interface, signature="s",
1119
1231
                           access="readwrite")
1153
1265
        self._pipe.send(('init', fpr, address))
1154
1266
        if not self._pipe.recv():
1155
1267
            raise KeyError()
1156
 
 
 
1268
    
1157
1269
    def __getattribute__(self, name):
1158
1270
        if(name == '_pipe'):
1159
1271
            return super(ProxyClient, self).__getattribute__(name)
1166
1278
                self._pipe.send(('funcall', name, args, kwargs))
1167
1279
                return self._pipe.recv()[1]
1168
1280
            return func
1169
 
 
 
1281
    
1170
1282
    def __setattr__(self, name, value):
1171
1283
        if(name == '_pipe'):
1172
1284
            return super(ProxyClient, self).__setattr__(name, value)
1173
1285
        self._pipe.send(('setattr', name, value))
1174
1286
 
 
1287
class ClientDBusTransitional(ClientDBus):
 
1288
    __metaclass__ = AlternateDBusNamesMetaclass
1175
1289
 
1176
1290
class ClientHandler(socketserver.BaseRequestHandler, object):
1177
1291
    """A class to handle client connections.
1185
1299
                        unicode(self.client_address))
1186
1300
            logger.debug("Pipe FD: %d",
1187
1301
                         self.server.child_pipe.fileno())
1188
 
 
 
1302
            
1189
1303
            session = (gnutls.connection
1190
1304
                       .ClientSession(self.request,
1191
1305
                                      gnutls.connection
1192
1306
                                      .X509Credentials()))
1193
 
 
 
1307
            
1194
1308
            # Note: gnutls.connection.X509Credentials is really a
1195
1309
            # generic GnuTLS certificate credentials object so long as
1196
1310
            # no X.509 keys are added to it.  Therefore, we can use it
1197
1311
            # here despite using OpenPGP certificates.
1198
 
 
 
1312
            
1199
1313
            #priority = ':'.join(("NONE", "+VERS-TLS1.1",
1200
1314
            #                      "+AES-256-CBC", "+SHA1",
1201
1315
            #                      "+COMP-NULL", "+CTYPE-OPENPGP",
1207
1321
            (gnutls.library.functions
1208
1322
             .gnutls_priority_set_direct(session._c_object,
1209
1323
                                         priority, None))
1210
 
 
 
1324
            
1211
1325
            # Start communication using the Mandos protocol
1212
1326
            # Get protocol number
1213
1327
            line = self.request.makefile().readline()
1218
1332
            except (ValueError, IndexError, RuntimeError) as error:
1219
1333
                logger.error("Unknown protocol version: %s", error)
1220
1334
                return
1221
 
 
 
1335
            
1222
1336
            # Start GnuTLS connection
1223
1337
            try:
1224
1338
                session.handshake()
1228
1342
                # established.  Just abandon the request.
1229
1343
                return
1230
1344
            logger.debug("Handshake succeeded")
1231
 
 
 
1345
            
1232
1346
            approval_required = False
1233
1347
            try:
1234
1348
                try:
1239
1353
                    logger.warning("Bad certificate: %s", error)
1240
1354
                    return
1241
1355
                logger.debug("Fingerprint: %s", fpr)
1242
 
 
 
1356
                
1243
1357
                try:
1244
1358
                    client = ProxyClient(child_pipe, fpr,
1245
1359
                                         self.client_address)
1257
1371
                                       client.name)
1258
1372
                        if self.server.use_dbus:
1259
1373
                            # Emit D-Bus signal
1260
 
                            client.Rejected("Disabled")                    
 
1374
                            client.Rejected("Disabled")
1261
1375
                        return
1262
1376
                    
1263
1377
                    if client._approved or not client.approval_delay:
1280
1394
                        return
1281
1395
                    
1282
1396
                    #wait until timeout or approved
1283
 
                    #x = float(client._timedelta_to_milliseconds(delay))
 
1397
                    #x = float(client
 
1398
                    #          ._timedelta_to_milliseconds(delay))
1284
1399
                    time = datetime.datetime.now()
1285
1400
                    client.changedstate.acquire()
1286
 
                    client.changedstate.wait(float(client._timedelta_to_milliseconds(delay) / 1000))
 
1401
                    (client.changedstate.wait
 
1402
                     (float(client._timedelta_to_milliseconds(delay)
 
1403
                            / 1000)))
1287
1404
                    client.changedstate.release()
1288
1405
                    time2 = datetime.datetime.now()
1289
1406
                    if (time2 - time) >= delay:
1311
1428
                                 sent, len(client.secret)
1312
1429
                                 - (sent_size + sent))
1313
1430
                    sent_size += sent
1314
 
 
 
1431
                
1315
1432
                logger.info("Sending secret to %s", client.name)
1316
1433
                # bump the timeout as if seen
1317
1434
                client.checked_ok(client.extended_timeout)
1405
1522
        multiprocessing.Process(target = self.sub_process_main,
1406
1523
                                args = (request, address)).start()
1407
1524
 
 
1525
 
1408
1526
class MultiprocessingMixInWithPipe(MultiprocessingMixIn, object):
1409
1527
    """ adds a pipe to the MixIn """
1410
1528
    def process_request(self, request, client_address):
1413
1531
        This function creates a new pipe in self.pipe
1414
1532
        """
1415
1533
        parent_pipe, self.child_pipe = multiprocessing.Pipe()
1416
 
 
 
1534
        
1417
1535
        super(MultiprocessingMixInWithPipe,
1418
1536
              self).process_request(request, client_address)
1419
1537
        self.child_pipe.close()
1420
1538
        self.add_pipe(parent_pipe)
1421
 
 
 
1539
    
1422
1540
    def add_pipe(self, parent_pipe):
1423
1541
        """Dummy function; override as necessary"""
1424
1542
        raise NotImplementedError
1425
1543
 
 
1544
 
1426
1545
class IPv6_TCPServer(MultiprocessingMixInWithPipe,
1427
1546
                     socketserver.TCPServer, object):
1428
1547
    """IPv6-capable TCP server.  Accepts 'None' as address and/or port
1519
1638
        gobject.io_add_watch(parent_pipe.fileno(),
1520
1639
                             gobject.IO_IN | gobject.IO_HUP,
1521
1640
                             functools.partial(self.handle_ipc,
1522
 
                                               parent_pipe = parent_pipe))
 
1641
                                               parent_pipe =
 
1642
                                               parent_pipe))
1523
1643
        
1524
1644
    def handle_ipc(self, source, condition, parent_pipe=None,
1525
1645
                   client_object=None):
1558
1678
                            "dress: %s", fpr, address)
1559
1679
                if self.use_dbus:
1560
1680
                    # Emit D-Bus signal
1561
 
                    mandos_dbus_service.ClientNotFound(fpr, address[0])
 
1681
                    mandos_dbus_service.ClientNotFound(fpr,
 
1682
                                                       address[0])
1562
1683
                parent_pipe.send(False)
1563
1684
                return False
1564
1685
            
1565
1686
            gobject.io_add_watch(parent_pipe.fileno(),
1566
1687
                                 gobject.IO_IN | gobject.IO_HUP,
1567
1688
                                 functools.partial(self.handle_ipc,
1568
 
                                                   parent_pipe = parent_pipe,
1569
 
                                                   client_object = client))
 
1689
                                                   parent_pipe =
 
1690
                                                   parent_pipe,
 
1691
                                                   client_object =
 
1692
                                                   client))
1570
1693
            parent_pipe.send(True)
1571
 
            # remove the old hook in favor of the new above hook on same fileno
 
1694
            # remove the old hook in favor of the new above hook on
 
1695
            # same fileno
1572
1696
            return False
1573
1697
        if command == 'funcall':
1574
1698
            funcname = request[1]
1575
1699
            args = request[2]
1576
1700
            kwargs = request[3]
1577
1701
            
1578
 
            parent_pipe.send(('data', getattr(client_object, funcname)(*args, **kwargs)))
1579
 
 
 
1702
            parent_pipe.send(('data', getattr(client_object,
 
1703
                                              funcname)(*args,
 
1704
                                                         **kwargs)))
 
1705
        
1580
1706
        if command == 'getattr':
1581
1707
            attrname = request[1]
1582
1708
            if callable(client_object.__getattribute__(attrname)):
1583
1709
                parent_pipe.send(('function',))
1584
1710
            else:
1585
 
                parent_pipe.send(('data', client_object.__getattribute__(attrname)))
 
1711
                parent_pipe.send(('data', client_object
 
1712
                                  .__getattribute__(attrname)))
1586
1713
        
1587
1714
        if command == 'setattr':
1588
1715
            attrname = request[1]
1589
1716
            value = request[2]
1590
1717
            setattr(client_object, attrname, value)
1591
 
 
 
1718
        
1592
1719
        return True
1593
1720
 
1594
1721
 
1773
1900
    debuglevel = server_settings["debuglevel"]
1774
1901
    use_dbus = server_settings["use_dbus"]
1775
1902
    use_ipv6 = server_settings["use_ipv6"]
1776
 
 
 
1903
    
1777
1904
    if server_settings["servicename"] != "Mandos":
1778
1905
        syslogger.setFormatter(logging.Formatter
1779
1906
                               ('Mandos (%s) [%%(process)d]:'
1840
1967
        level = getattr(logging, debuglevel.upper())
1841
1968
        syslogger.setLevel(level)
1842
1969
        console.setLevel(level)
1843
 
 
 
1970
    
1844
1971
    if debug:
1845
1972
        # Enable all possible GnuTLS debugging
1846
1973
        
1877
2004
    # End of Avahi example code
1878
2005
    if use_dbus:
1879
2006
        try:
1880
 
            bus_name = dbus.service.BusName("se.bsnet.fukt.Mandos",
 
2007
            bus_name = dbus.service.BusName("se.recompile.Mandos",
1881
2008
                                            bus, do_not_queue=True)
 
2009
            old_bus_name = (dbus.service.BusName
 
2010
                            ("se.bsnet.fukt.Mandos", bus,
 
2011
                             do_not_queue=True))
1882
2012
        except dbus.exceptions.NameExistsException as e:
1883
2013
            logger.error(unicode(e) + ", disabling D-Bus")
1884
2014
            use_dbus = False
1897
2027
    
1898
2028
    client_class = Client
1899
2029
    if use_dbus:
1900
 
        client_class = functools.partial(ClientDBus, bus = bus)
 
2030
        client_class = functools.partial(ClientDBusTransitional,
 
2031
                                         bus = bus)
1901
2032
    def client_config_items(config, section):
1902
2033
        special_settings = {
1903
2034
            "approved_by_default":
1933
2064
        del pidfilename
1934
2065
        
1935
2066
        signal.signal(signal.SIGINT, signal.SIG_IGN)
1936
 
 
 
2067
    
1937
2068
    signal.signal(signal.SIGHUP, lambda signum, frame: sys.exit())
1938
2069
    signal.signal(signal.SIGTERM, lambda signum, frame: sys.exit())
1939
2070
    
1942
2073
            """A D-Bus proxy object"""
1943
2074
            def __init__(self):
1944
2075
                dbus.service.Object.__init__(self, bus, "/")
1945
 
            _interface = "se.bsnet.fukt.Mandos"
 
2076
            _interface = "se.recompile.Mandos"
1946
2077
            
1947
2078
            @dbus.service.signal(_interface, signature="o")
1948
2079
            def ClientAdded(self, objpath):
1990
2121
            
1991
2122
            del _interface
1992
2123
        
1993
 
        mandos_dbus_service = MandosDBusService()
 
2124
        class MandosDBusServiceTransitional(MandosDBusService):
 
2125
            __metaclass__ = AlternateDBusNamesMetaclass
 
2126
        mandos_dbus_service = MandosDBusServiceTransitional()
1994
2127
    
1995
2128
    def cleanup():
1996
2129
        "Cleanup function; run on exit"
2005
2138
            client.disable(quiet=True)
2006
2139
            if use_dbus:
2007
2140
                # Emit D-Bus signal
2008
 
                mandos_dbus_service.ClientRemoved(client.dbus_object_path,
 
2141
                mandos_dbus_service.ClientRemoved(client
 
2142
                                                  .dbus_object_path,
2009
2143
                                                  client.name)
2010
2144
    
2011
2145
    atexit.register(cleanup)
2060
2194
    # Must run before the D-Bus bus name gets deregistered
2061
2195
    cleanup()
2062
2196
 
 
2197
 
2063
2198
if __name__ == '__main__':
2064
2199
    main()