/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-ctl: Made work again after D-Bus API changes.
  (datetime_to_milliseconds): Renamed to "timedelta_to_milliseconds".
                              All callers changed.
  (milliseconds_to_string): Use clearer mapping string format.
  (string_to_delta): Add some comments.

Show diffs side-by-side

added added

removed removed

Lines of Context:
79
79
        SO_BINDTODEVICE = None
80
80
 
81
81
 
82
 
version = "1.0.14"
 
82
version = "1.0.12"
83
83
 
84
84
logger = logging.Logger(u'mandos')
85
85
syslogger = (logging.handlers.SysLogHandler
292
292
        elif u"secfile" in config:
293
293
            with closing(open(os.path.expanduser
294
294
                              (os.path.expandvars
295
 
                               (config[u"secfile"])),
296
 
                              "rb")) as secfile:
 
295
                               (config[u"secfile"])))) as secfile:
297
296
                self.secret = secfile.read()
298
297
        else:
299
298
            raise TypeError(u"No secret or secfile for client %s"
325
324
        self.checker_initiator_tag = (gobject.timeout_add
326
325
                                      (self.interval_milliseconds(),
327
326
                                       self.start_checker))
 
327
        # Also start a new checker *right now*.
 
328
        self.start_checker()
328
329
        # Schedule a disable() when 'timeout' has passed
329
330
        self.disable_initiator_tag = (gobject.timeout_add
330
331
                                   (self.timeout_milliseconds(),
331
332
                                    self.disable))
332
333
        self.enabled = True
333
 
        # Also start a new checker *right now*.
334
 
        self.start_checker()
335
334
    
336
 
    def disable(self, quiet=True):
 
335
    def disable(self):
337
336
        """Disable this client."""
338
337
        if not getattr(self, "enabled", False):
339
338
            return False
340
 
        if not quiet:
341
 
            logger.info(u"Disabling client %s", self.name)
 
339
        logger.info(u"Disabling client %s", self.name)
342
340
        if getattr(self, u"disable_initiator_tag", False):
343
341
            gobject.source_remove(self.disable_initiator_tag)
344
342
            self.disable_initiator_tag = None
400
398
        # is as it should be.
401
399
        
402
400
        # If a checker exists, make sure it is not a zombie
403
 
        try:
 
401
        if self.checker is not None:
404
402
            pid, status = os.waitpid(self.checker.pid, os.WNOHANG)
405
 
        except (AttributeError, OSError), error:
406
 
            if (isinstance(error, OSError)
407
 
                and error.errno != errno.ECHILD):
408
 
                raise error
409
 
        else:
410
403
            if pid:
411
404
                logger.warning(u"Checker was a zombie")
412
405
                gobject.source_remove(self.checker_callback_tag)
468
461
        logger.debug(u"Stopping checker for %(name)s", vars(self))
469
462
        try:
470
463
            os.kill(self.checker.pid, signal.SIGTERM)
471
 
            #time.sleep(0.5)
 
464
            #os.sleep(0.5)
472
465
            #if self.checker.poll() is None:
473
466
            #    os.kill(self.checker.pid, signal.SIGKILL)
474
467
        except OSError, error:
627
620
        """Standard D-Bus method, overloaded to insert property tags.
628
621
        """
629
622
        xmlstring = dbus.service.Object.Introspect(self, object_path,
630
 
                                                   connection)
631
 
        try:
632
 
            document = xml.dom.minidom.parseString(xmlstring)
633
 
            def make_tag(document, name, prop):
634
 
                e = document.createElement(u"property")
635
 
                e.setAttribute(u"name", name)
636
 
                e.setAttribute(u"type", prop._dbus_signature)
637
 
                e.setAttribute(u"access", prop._dbus_access)
638
 
                return e
639
 
            for if_tag in document.getElementsByTagName(u"interface"):
640
 
                for tag in (make_tag(document, name, prop)
641
 
                            for name, prop
642
 
                            in self._get_all_dbus_properties()
643
 
                            if prop._dbus_interface
644
 
                            == if_tag.getAttribute(u"name")):
645
 
                    if_tag.appendChild(tag)
646
 
                # Add the names to the return values for the
647
 
                # "org.freedesktop.DBus.Properties" methods
648
 
                if (if_tag.getAttribute(u"name")
649
 
                    == u"org.freedesktop.DBus.Properties"):
650
 
                    for cn in if_tag.getElementsByTagName(u"method"):
651
 
                        if cn.getAttribute(u"name") == u"Get":
652
 
                            for arg in cn.getElementsByTagName(u"arg"):
653
 
                                if (arg.getAttribute(u"direction")
654
 
                                    == u"out"):
655
 
                                    arg.setAttribute(u"name", u"value")
656
 
                        elif cn.getAttribute(u"name") == u"GetAll":
657
 
                            for arg in cn.getElementsByTagName(u"arg"):
658
 
                                if (arg.getAttribute(u"direction")
659
 
                                    == u"out"):
660
 
                                    arg.setAttribute(u"name", u"props")
661
 
            xmlstring = document.toxml(u"utf-8")
662
 
            document.unlink()
663
 
        except (AttributeError, xml.dom.DOMException,
664
 
                xml.parsers.expat.ExpatError), error:
665
 
            logger.error(u"Failed to override Introspection method",
666
 
                         error)
 
623
                                           connection)
 
624
        document = xml.dom.minidom.parseString(xmlstring)
 
625
        del xmlstring
 
626
        def make_tag(document, name, prop):
 
627
            e = document.createElement(u"property")
 
628
            e.setAttribute(u"name", name)
 
629
            e.setAttribute(u"type", prop._dbus_signature)
 
630
            e.setAttribute(u"access", prop._dbus_access)
 
631
            return e
 
632
        for if_tag in document.getElementsByTagName(u"interface"):
 
633
            for tag in (make_tag(document, name, prop)
 
634
                        for name, prop
 
635
                        in self._get_all_dbus_properties()
 
636
                        if prop._dbus_interface
 
637
                        == if_tag.getAttribute(u"name")):
 
638
                if_tag.appendChild(tag)
 
639
        xmlstring = document.toxml(u"utf-8")
 
640
        document.unlink()
667
641
        return xmlstring
668
642
 
669
643
 
706
680
                                       variant_level=1))
707
681
        return r
708
682
    
709
 
    def disable(self, quiet = False):
 
683
    def disable(self, signal = True):
710
684
        oldstate = getattr(self, u"enabled", False)
711
 
        r = Client.disable(self, quiet=quiet)
712
 
        if not quiet and oldstate != self.enabled:
 
685
        r = Client.disable(self)
 
686
        if signal and oldstate != self.enabled:
713
687
            # Emit D-Bus signal
714
688
            self.PropertyChanged(dbus.String(u"enabled"),
715
689
                                 dbus.Boolean(False, variant_level=1))
807
781
        "D-Bus signal"
808
782
        pass
809
783
    
810
 
    # GotSecret - signal
 
784
    # ReceivedSecret - signal
811
785
    @dbus.service.signal(_interface)
812
 
    def GotSecret(self):
 
786
    def ReceivedSecret(self):
813
787
        "D-Bus signal"
814
788
        pass
815
789
    
1302
1276
                    client.checked_ok()
1303
1277
                    if self.use_dbus:
1304
1278
                        # Emit D-Bus signal
1305
 
                        client.GotSecret()
 
1279
                        client.ReceivedSecret()
1306
1280
                    break
1307
1281
            else:
1308
1282
                logger.error(u"Sending secret to unknown client %s",
1346
1320
            elif suffix == u"w":
1347
1321
                delta = datetime.timedelta(0, 0, 0, 0, 0, 0, value)
1348
1322
            else:
1349
 
                raise ValueError(u"Unknown suffix %r" % suffix)
1350
 
        except (ValueError, IndexError), e:
1351
 
            raise ValueError(e.message)
 
1323
                raise ValueError
 
1324
        except (ValueError, IndexError):
 
1325
            raise ValueError
1352
1326
        timevalue += delta
1353
1327
    return timevalue
1354
1328
 
1393
1367
        null = os.open(os.path.devnull, os.O_NOCTTY | os.O_RDWR)
1394
1368
        if not stat.S_ISCHR(os.fstat(null).st_mode):
1395
1369
            raise OSError(errno.ENODEV,
1396
 
                          u"%s not a character device"
1397
 
                          % os.path.devnull)
 
1370
                          u"/dev/null not a character device")
1398
1371
        os.dup2(null, sys.stdin.fileno())
1399
1372
        os.dup2(null, sys.stdout.fileno())
1400
1373
        os.dup2(null, sys.stderr.fileno())
1567
1540
    bus = dbus.SystemBus()
1568
1541
    # End of Avahi example code
1569
1542
    if use_dbus:
1570
 
        try:
1571
 
            bus_name = dbus.service.BusName(u"se.bsnet.fukt.Mandos",
1572
 
                                            bus, do_not_queue=True)
1573
 
        except dbus.exceptions.NameExistsException, e:
1574
 
            logger.error(unicode(e) + u", disabling D-Bus")
1575
 
            use_dbus = False
1576
 
            server_settings[u"use_dbus"] = False
1577
 
            tcp_server.use_dbus = False
 
1543
        bus_name = dbus.service.BusName(u"se.bsnet.fukt.Mandos", bus)
1578
1544
    protocol = avahi.PROTO_INET6 if use_ipv6 else avahi.PROTO_INET
1579
1545
    service = AvahiService(name = server_settings[u"servicename"],
1580
1546
                           servicetype = u"_mandos._tcp",
1618
1584
        pass
1619
1585
    del pidfilename
1620
1586
    
 
1587
    def cleanup():
 
1588
        "Cleanup function; run on exit"
 
1589
        service.cleanup()
 
1590
        
 
1591
        while tcp_server.clients:
 
1592
            client = tcp_server.clients.pop()
 
1593
            client.disable_hook = None
 
1594
            client.disable()
 
1595
    
 
1596
    atexit.register(cleanup)
 
1597
    
1621
1598
    if not debug:
1622
1599
        signal.signal(signal.SIGINT, signal.SIG_IGN)
1623
1600
    signal.signal(signal.SIGHUP, lambda signum, frame: sys.exit())
1668
1645
                        tcp_server.clients.remove(c)
1669
1646
                        c.remove_from_connection()
1670
1647
                        # Don't signal anything except ClientRemoved
1671
 
                        c.disable(quiet=True)
 
1648
                        c.disable(signal=False)
1672
1649
                        # Emit D-Bus signal
1673
1650
                        self.ClientRemoved(object_path, c.name)
1674
1651
                        return
1675
 
                raise KeyError(object_path)
 
1652
                raise KeyError
1676
1653
            
1677
1654
            del _interface
1678
1655
        
1679
1656
        mandos_dbus_service = MandosDBusService()
1680
1657
    
1681
 
    def cleanup():
1682
 
        "Cleanup function; run on exit"
1683
 
        service.cleanup()
1684
 
        
1685
 
        while tcp_server.clients:
1686
 
            client = tcp_server.clients.pop()
1687
 
            if use_dbus:
1688
 
                client.remove_from_connection()
1689
 
            client.disable_hook = None
1690
 
            # Don't signal anything except ClientRemoved
1691
 
            client.disable(quiet=True)
1692
 
            if use_dbus:
1693
 
                # Emit D-Bus signal
1694
 
                mandos_dbus_service.ClientRemoved(client.dbus_object_path,
1695
 
                                                  client.name)
1696
 
    
1697
 
    atexit.register(cleanup)
1698
 
    
1699
1658
    for client in tcp_server.clients:
1700
1659
        if use_dbus:
1701
1660
            # Emit D-Bus signal
1724
1683
            service.activate()
1725
1684
        except dbus.exceptions.DBusException, error:
1726
1685
            logger.critical(u"DBusException: %s", error)
1727
 
            cleanup()
1728
1686
            sys.exit(1)
1729
1687
        # End of Avahi example code
1730
1688
        
1737
1695
        main_loop.run()
1738
1696
    except AvahiError, error:
1739
1697
        logger.critical(u"AvahiError: %s", error)
1740
 
        cleanup()
1741
1698
        sys.exit(1)
1742
1699
    except KeyboardInterrupt:
1743
1700
        if debug:
1744
1701
            print >> sys.stderr
1745
1702
        logger.debug(u"Server received KeyboardInterrupt")
1746
1703
    logger.debug(u"Server exiting")
1747
 
    # Must run before the D-Bus bus name gets deregistered
1748
 
    cleanup()
1749
1704
 
1750
1705
if __name__ == '__main__':
1751
1706
    main()