/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: 2008-08-16 03:29:08 UTC
  • Revision ID: teddy@fukt.bsnet.se-20080816032908-ihw7c05r2mnyk389
Add feature to specify custom environment variables for plugins.

* plugin-runner.c (plugin): New members "environ" and "envc" to
                            contain possible custom environment.
  (getplugin): Return NULL on failure instead of doing exit(); all
               callers changed.
  (add_to_char_array): New helper function for "add_argument" and
                       "add_environment".
  (addargument): Renamed to "add_argument".  Return bool.  Call
                 "add_to_char_array" to actually do things.
  (add_environment): New; analogous to "add_argument".
  (addcustomargument): Renamed to "add_to_argv" to avoid confusion
                       with "add_argument".
  (main): New options "--global-envs" and "--envs-for" to specify
          custom environment for plugins.  Print environment for
          plugins in debug mode.  Use asprintf instead of strcpy and
          strcat.  Use execve() for plugins with custom environments.
          Free environment for plugin when freeing plugin list.

Show diffs side-by-side

added added

removed removed

Lines of Context:
24
24
#     GNU General Public License for more details.
25
25
26
26
# You should have received a copy of the GNU General Public License
27
 
# along with this program.  If not, see
28
 
# <http://www.gnu.org/licenses/>.
 
27
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
29
28
30
29
# Contact the authors at <mandos@fukt.bsnet.se>.
31
30
124
123
    def rename(self):
125
124
        """Derived from the Avahi example code"""
126
125
        if self.rename_count >= self.max_renames:
127
 
            logger.critical(u"No suitable Zeroconf service name found"
128
 
                            u" after %i retries, exiting.",
129
 
                            rename_count)
 
126
            logger.critical(u"No suitable service name found after %i"
 
127
                            u" retries, exiting.", rename_count)
130
128
            raise AvahiServiceError("Too many renames")
131
129
        self.name = server.GetAlternativeServiceName(self.name)
132
 
        logger.info(u"Changing Zeroconf service name to %r ...",
133
 
                    str(self.name))
 
130
        logger.info(u"Changing name to %r ...", str(self.name))
134
131
        syslogger.setFormatter(logging.Formatter\
135
132
                               ('Mandos (%s): %%(levelname)s:'
136
133
                               ' %%(message)s' % self.name))
151
148
                     avahi.DBUS_INTERFACE_ENTRY_GROUP)
152
149
            group.connect_to_signal('StateChanged',
153
150
                                    entry_group_state_changed)
154
 
        logger.debug(u"Adding Zeroconf service '%s' of type '%s' ...",
 
151
        logger.debug(u"Adding service '%s' of type '%s' ...",
155
152
                     service.name, service.type)
156
153
        group.AddService(
157
154
                self.interface,         # interface
340
337
            try:
341
338
                logger.info(u"Starting checker %r for %s",
342
339
                            command, self.name)
343
 
                # We don't need to redirect stdout and stderr, since
344
 
                # in normal mode, that is already done by daemon(),
345
 
                # and in debug mode we don't want to.  (Stdin is
346
 
                # always replaced by /dev/null.)
347
340
                self.checker = subprocess.Popen(command,
348
341
                                                close_fds=True,
349
342
                                                shell=True, cwd="/")
350
343
                self.checker_callback_tag = gobject.child_watch_add\
351
344
                                            (self.checker.pid,
352
345
                                             self.checker_callback)
353
 
            except OSError, error:
 
346
            except subprocess.OSError, error:
354
347
                logger.error(u"Failed to start subprocess: %s",
355
348
                             error)
356
349
        # Re-run this periodically if run by gobject.timeout_add
413
406
    gnutls.library.functions.gnutls_openpgp_crt_import\
414
407
                    (crt, ctypes.byref(datum),
415
408
                     gnutls.library.constants.GNUTLS_OPENPGP_FMT_RAW)
416
 
    # Verify the self signature in the key
417
 
    crtverify = ctypes.c_uint();
418
 
    gnutls.library.functions.gnutls_openpgp_crt_verify_self\
419
 
        (crt, 0, ctypes.byref(crtverify))
420
 
    if crtverify.value != 0:
421
 
        gnutls.library.functions.gnutls_openpgp_crt_deinit(crt)
422
 
        raise gnutls.errors.CertificateSecurityError("Verify failed")
423
409
    # New buffer for the fingerprint
424
410
    buffer = ctypes.create_string_buffer(20)
425
411
    buffer_length = ctypes.c_size_t()
577
563
    datetime.timedelta(1)
578
564
    >>> string_to_delta(u'1w')
579
565
    datetime.timedelta(7)
580
 
    >>> string_to_delta('5m 30s')
581
 
    datetime.timedelta(0, 330)
582
566
    """
583
 
    timevalue = datetime.timedelta(0)
584
 
    for s in interval.split():
585
 
        try:
586
 
            suffix=unicode(s[-1])
587
 
            value=int(s[:-1])
588
 
            if suffix == u"d":
589
 
                delta = datetime.timedelta(value)
590
 
            elif suffix == u"s":
591
 
                delta = datetime.timedelta(0, value)
592
 
            elif suffix == u"m":
593
 
                delta = datetime.timedelta(0, 0, 0, 0, value)
594
 
            elif suffix == u"h":
595
 
                delta = datetime.timedelta(0, 0, 0, 0, 0, value)
596
 
            elif suffix == u"w":
597
 
                delta = datetime.timedelta(0, 0, 0, 0, 0, 0, value)
598
 
            else:
599
 
                raise ValueError
600
 
        except (ValueError, IndexError):
 
567
    try:
 
568
        suffix=unicode(interval[-1])
 
569
        value=int(interval[:-1])
 
570
        if suffix == u"d":
 
571
            delta = datetime.timedelta(value)
 
572
        elif suffix == u"s":
 
573
            delta = datetime.timedelta(0, value)
 
574
        elif suffix == u"m":
 
575
            delta = datetime.timedelta(0, 0, 0, 0, value)
 
576
        elif suffix == u"h":
 
577
            delta = datetime.timedelta(0, 0, 0, 0, 0, value)
 
578
        elif suffix == u"w":
 
579
            delta = datetime.timedelta(0, 0, 0, 0, 0, 0, value)
 
580
        else:
601
581
            raise ValueError
602
 
        timevalue += delta
603
 
    return timevalue
 
582
    except (ValueError, IndexError):
 
583
        raise ValueError
 
584
    return delta
604
585
 
605
586
 
606
587
def server_state_changed(state):
607
588
    """Derived from the Avahi example code"""
608
589
    if state == avahi.SERVER_COLLISION:
609
 
        logger.error(u"Zeroconf server name collision")
 
590
        logger.error(u"Server name collision")
610
591
        service.remove()
611
592
    elif state == avahi.SERVER_RUNNING:
612
593
        service.add()
614
595
 
615
596
def entry_group_state_changed(state, error):
616
597
    """Derived from the Avahi example code"""
617
 
    logger.debug(u"Avahi state change: %i", state)
 
598
    logger.debug(u"state change: %i", state)
618
599
    
619
600
    if state == avahi.ENTRY_GROUP_ESTABLISHED:
620
 
        logger.debug(u"Zeroconf service established.")
 
601
        logger.debug(u"Service established.")
621
602
    elif state == avahi.ENTRY_GROUP_COLLISION:
622
 
        logger.warning(u"Zeroconf service name collision.")
 
603
        logger.warning(u"Service name collision.")
623
604
        service.rename()
624
605
    elif state == avahi.ENTRY_GROUP_FAILURE:
625
 
        logger.critical(u"Avahi: Error in group state changed %s",
 
606
        logger.critical(u"Error in group state changed %s",
626
607
                        unicode(error))
627
608
        raise AvahiGroupError("State changed: %s", str(error))
628
609
 
719
700
    server_config = ConfigParser.SafeConfigParser(server_defaults)
720
701
    del server_defaults
721
702
    server_config.read(os.path.join(options.configdir, "mandos.conf"))
 
703
    server_section = "server"
722
704
    # Convert the SafeConfigParser object to a dict
723
 
    server_settings = server_config.defaults()
 
705
    server_settings = dict(server_config.items(server_section))
724
706
    # Use getboolean on the boolean config option
725
707
    server_settings["debug"] = server_config.getboolean\
726
 
                               ("DEFAULT", "debug")
 
708
                               (server_section, "debug")
727
709
    del server_config
728
710
    
729
711
    # Override the settings from the config file with command line
751
733
    # Parse config file with clients
752
734
    client_defaults = { "timeout": "1h",
753
735
                        "interval": "5m",
754
 
                        "checker": "fping -q -- %(host)s",
755
 
                        "host": "",
 
736
                        "checker": "fping -q -- %%(host)s",
756
737
                        }
757
738
    client_config = ConfigParser.SafeConfigParser(client_defaults)
758
739
    client_config.read(os.path.join(server_settings["configdir"],
762
743
    service = AvahiService(name = server_settings["servicename"],
763
744
                           type = "_mandos._tcp", );
764
745
    if server_settings["interface"]:
765
 
        service.interface = if_nametoindex\
766
 
                            (server_settings["interface"])
 
746
        service.interface = if_nametoindex(server_settings["interface"])
767
747
    
768
748
    global main_loop
769
749
    global bus
772
752
    DBusGMainLoop(set_as_default=True )
773
753
    main_loop = gobject.MainLoop()
774
754
    bus = dbus.SystemBus()
775
 
    server = dbus.Interface(bus.get_object(avahi.DBUS_NAME,
776
 
                                           avahi.DBUS_PATH_SERVER),
777
 
                            avahi.DBUS_INTERFACE_SERVER)
 
755
    server = dbus.Interface(
 
756
            bus.get_object( avahi.DBUS_NAME, avahi.DBUS_PATH_SERVER ),
 
757
            avahi.DBUS_INTERFACE_SERVER )
778
758
    # End of Avahi example code
779
759
    
780
760
    clients = Set()
793
773
        logger.critical(u"No clients defined")
794
774
        sys.exit(1)
795
775
    
796
 
    if debug:
797
 
        # Redirect stdin so all checkers get /dev/null
798
 
        null = os.open(os.path.devnull, os.O_NOCTTY | os.O_RDWR)
799
 
        os.dup2(null, sys.stdin.fileno())
800
 
        if null > 2:
801
 
            os.close(null)
802
 
    else:
803
 
        # No console logging
 
776
    if not debug:
804
777
        logger.removeHandler(console)
805
 
        # Close all input and output, do double fork, etc.
806
778
        daemon()
807
779
    
808
780
    pidfilename = "/var/run/mandos/mandos.pid"