/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: 2013-05-22 20:00:18 UTC
  • Revision ID: teddy@recompile.se-20130522200018-xtbddz21pl7c69kw
* mandos: Bug fix: Don't print output from checkers when running in
          foreground.
          Bug fix: Do not fail when client is removed from
          clients.conf but saved settings remain.
  (Client.server_settings): New attribute.
  (Client.__init__): Take new "server_settings" keyword argument.  All
                     callers changed.
  (Client.start_checker): Redirect stdout and stderr for checkers when
                          running in foreground.
  (main): New "wnull" global variable for a writable /dev/null file.
          Do not restore settings for clients no longer in config file.
  (main/cleanup): Close wnull file object.  Do not save client
                  attribute "server_settings"
* mandos-monitor: Update to work in Urwid 1.0.1.
                  Adapt to work in both Python 3 and Python 2.

Show diffs side-by-side

added added

removed removed

Lines of Context:
440
440
    runtime_expansions: Allowed attributes for runtime expansion.
441
441
    expires:    datetime.datetime(); time (UTC) when a client will be
442
442
                disabled, or None
 
443
    server_settings: The server_settings dict from main()
443
444
    """
444
445
    
445
446
    runtime_expansions = ("approval_delay", "approval_duration",
520
521
        
521
522
        return settings
522
523
    
523
 
    def __init__(self, settings, name = None):
 
524
    def __init__(self, settings, name = None, server_settings=None):
524
525
        self.name = name
 
526
        if server_settings is None:
 
527
            server_settings = {}
 
528
        self.server_settings = server_settings
525
529
        # adding all client settings
526
530
        for setting, value in settings.iteritems():
527
531
            setattr(self, setting, value)
711
715
                # in normal mode, that is already done by daemon(),
712
716
                # and in debug mode we don't want to.  (Stdin is
713
717
                # always replaced by /dev/null.)
 
718
                # The exception is when not debugging but nevertheless
 
719
                # running in the foreground; use the previously
 
720
                # created wnull.
 
721
                popen_args = {}
 
722
                if (not self.server_settings["debug"]
 
723
                    and self.server_settings["foreground"]):
 
724
                    popen_args.update({"stdout": wnull,
 
725
                                       "stderr": wnull })
714
726
                self.checker = subprocess.Popen(command,
715
727
                                                close_fds=True,
716
 
                                                shell=True, cwd="/")
 
728
                                                shell=True, cwd="/",
 
729
                                                **popen_args)
717
730
            except OSError as error:
718
731
                logger.error("Failed to start subprocess",
719
732
                             exc_info=error)
2524
2537
    old_client_settings = {}
2525
2538
    clients_data = {}
2526
2539
    
 
2540
    # This is used to redirect stdout and stderr for checker processes
 
2541
    global wnull
 
2542
    wnull = open(os.devnull, "w") # A writable /dev/null
 
2543
    # Only used if server is running in foreground but not in debug
 
2544
    # mode
 
2545
    if debug or not foreground:
 
2546
        wnull.close()
 
2547
    
2527
2548
    # Get client data and settings from last running state.
2528
2549
    if server_settings["restore"]:
2529
2550
        try:
2545
2566
    
2546
2567
    with PGPEngine() as pgp:
2547
2568
        for client_name, client in clients_data.iteritems():
 
2569
            # Skip removed clients
 
2570
            if client_name not in client_settings:
 
2571
                continue
 
2572
            
2548
2573
            # Decide which value to use after restoring saved state.
2549
2574
            # We have three different values: Old config file,
2550
2575
            # new config file, and saved state.
2612
2637
    # Create all client objects
2613
2638
    for client_name, client in clients_data.iteritems():
2614
2639
        tcp_server.clients[client_name] = client_class(
2615
 
            name = client_name, settings = client)
 
2640
            name = client_name, settings = client,
 
2641
            server_settings = server_settings)
2616
2642
    
2617
2643
    if not tcp_server.clients:
2618
2644
        logger.warning("No clients defined")
2701
2727
        service.cleanup()
2702
2728
        
2703
2729
        multiprocessing.active_children()
 
2730
        wnull.close()
2704
2731
        if not (tcp_server.clients or client_settings):
2705
2732
            return
2706
2733
        
2718
2745
                # A list of attributes that can not be pickled
2719
2746
                # + secret.
2720
2747
                exclude = set(("bus", "changedstate", "secret",
2721
 
                               "checker"))
 
2748
                               "checker", "server_settings"))
2722
2749
                for name, typ in (inspect.getmembers
2723
2750
                                  (dbus.service.Object)):
2724
2751
                    exclude.add(name)