/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: 2024-09-08 05:08:20 UTC
  • Revision ID: teddy@recompile.se-20240908050820-jpkid6ufjb9n107o
Fix #1079588 by not outputting to stdout in maintainer scripts

From The Debconf Programmer's Tutorial: "Anything your maintainer
scripts output to standard output is passed into the frontend as a
command".  We must make sure to redirect stdout to stderr for every
command in the postinst and postrm scripts which might output to
stdout.

* debian/mandos-client.postinst (update_initramfs): Add "1>&2" to
  invocations of update-initramfs and /etc/kernel/postinst.d/dracut.
  (add_mandos_user): Add "1>&2" to invocations of usermod, groupmod,
  and adduser.
  (create_keys): Add "1>&2" to invocations of mandos-keygen,
  gpg-connect-agent, certtool, and openssl.
  (create_dh_params): Add "1>&2" to invocations of certtool and
  openssl.  Add "--force" option to "rm".
* debian/mandos-client.postrm (update_initramfs): Add "1>&2" to
  invocations of update-initramfs and /etc/kernel/postinst.d/dracut.

Closes: #1079588
Reported-By: Ben Hutchings <ben@decadent.org.uk>

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
# "AvahiService" class, and some lines in "main".
12
12
#
13
13
# Everything else is
14
 
# Copyright © 2008-2020 Teddy Hogeborn
15
 
# Copyright © 2008-2020 Björn Påhlsson
 
14
# Copyright © 2008-2022 Teddy Hogeborn
 
15
# Copyright © 2008-2022 Björn Påhlsson
16
16
#
17
17
# This file is part of Mandos.
18
18
#
143
143
if sys.version_info < (3, 2):
144
144
    configparser.Configparser = configparser.SafeConfigParser
145
145
 
146
 
version = "1.8.14"
 
146
version = "1.8.16"
147
147
stored_state_file = "clients.pickle"
148
148
 
149
149
log = logging.getLogger(os.path.basename(sys.argv[0]))
961
961
            # key_id() and fingerprint() functions
962
962
            client["key_id"] = (section.get("key_id", "").upper()
963
963
                                .replace(" ", ""))
964
 
            client["fingerprint"] = (section["fingerprint"].upper()
 
964
            client["fingerprint"] = (section.get("fingerprint",
 
965
                                                 "").upper()
965
966
                                     .replace(" ", ""))
 
967
            if not (client["key_id"] or client["fingerprint"]):
 
968
                log.error("Skipping client %s without key_id or"
 
969
                          " fingerprint", client_name)
 
970
                del settings[client_name]
 
971
                continue
966
972
            if "secret" in section:
967
973
                client["secret"] = codecs.decode(section["secret"]
968
974
                                                 .encode("utf-8"),
1045
1051
        if getattr(self, "enabled", False):
1046
1052
            # Already enabled
1047
1053
            return
1048
 
        self.expires = datetime.datetime.utcnow() + self.timeout
1049
1054
        self.enabled = True
1050
1055
        self.last_enabled = datetime.datetime.utcnow()
1051
1056
        self.init_checker()
1074
1079
    def __del__(self):
1075
1080
        self.disable()
1076
1081
 
1077
 
    def init_checker(self):
1078
 
        # Schedule a new checker to be started an 'interval' from now,
1079
 
        # and every interval from then on.
 
1082
    def init_checker(self, randomize_start=False):
 
1083
        # Schedule a new checker to be started a randomly selected
 
1084
        # time (a fraction of 'interval') from now.  This spreads out
 
1085
        # the startup of checkers over time when the server is
 
1086
        # started.
1080
1087
        if self.checker_initiator_tag is not None:
1081
1088
            GLib.source_remove(self.checker_initiator_tag)
 
1089
        interval_milliseconds = int(self.interval.total_seconds()
 
1090
                                    * 1000)
 
1091
        if randomize_start:
 
1092
            delay_milliseconds = random.randrange(
 
1093
                interval_milliseconds + 1)
 
1094
        else:
 
1095
            delay_milliseconds = interval_milliseconds
1082
1096
        self.checker_initiator_tag = GLib.timeout_add(
1083
 
            random.randrange(int(self.interval.total_seconds() * 1000
1084
 
                                 + 1)),
1085
 
            self.start_checker)
1086
 
        # Schedule a disable() when 'timeout' has passed
 
1097
            delay_milliseconds, self.start_checker, randomize_start)
 
1098
        delay = datetime.timedelta(0, 0, 0, delay_milliseconds)
 
1099
        # A checker might take up to an 'interval' of time, so we can
 
1100
        # expire at the soonest one interval after a checker was
 
1101
        # started.  Since the initial checker is delayed, the expire
 
1102
        # time might have to be extended.
 
1103
        now = datetime.datetime.utcnow()
 
1104
        self.expires = now + delay + self.interval
 
1105
        # Schedule a disable() at expire time
1087
1106
        if self.disable_initiator_tag is not None:
1088
1107
            GLib.source_remove(self.disable_initiator_tag)
1089
1108
        self.disable_initiator_tag = GLib.timeout_add(
1090
 
            int(self.timeout.total_seconds() * 1000), self.disable)
1091
 
        # Also start a new checker *right now*.
1092
 
        self.start_checker()
 
1109
            int((self.expires - now).total_seconds() * 1000),
 
1110
            self.disable)
1093
1111
 
1094
1112
    def checker_callback(self, source, condition, connection,
1095
1113
                         command):
1138
1156
    def need_approval(self):
1139
1157
        self.last_approval_request = datetime.datetime.utcnow()
1140
1158
 
1141
 
    def start_checker(self):
 
1159
    def start_checker(self, start_was_randomized=False):
1142
1160
        """Start a new checker subprocess if one is not running.
1143
1161
 
1144
1162
        If a checker already exists, leave it running and do
1194
1212
                GLib.IOChannel.unix_new(pipe[0].fileno()),
1195
1213
                GLib.PRIORITY_DEFAULT, GLib.IO_IN,
1196
1214
                self.checker_callback, pipe[0], command)
 
1215
        if start_was_randomized:
 
1216
            # We were started after a random delay; Schedule a new
 
1217
            # checker to be started an 'interval' from now, and every
 
1218
            # interval from then on.
 
1219
            now = datetime.datetime.utcnow()
 
1220
            self.checker_initiator_tag = GLib.timeout_add(
 
1221
                int(self.interval.total_seconds() * 1000),
 
1222
                self.start_checker)
 
1223
            self.expires = max(self.expires, now + self.interval)
 
1224
            # Don't start a new checker again after same random delay
 
1225
            return False
1197
1226
        # Re-run this periodically if run by GLib.timeout_add
1198
1227
        return True
1199
1228
 
3609
3638
            mandos_dbus_service.client_added_signal(client)
3610
3639
        # Need to initiate checking of clients
3611
3640
        if client.enabled:
3612
 
            client.init_checker()
 
3641
            client.init_checker(randomize_start=True)
3613
3642
 
3614
3643
    tcp_server.enable()
3615
3644
    tcp_server.server_activate()
3710
3739
#           default-directory dir)
3711
3740
#     (erase-buffer)
3712
3741
#     (compilation-mode))
3713
 
#   (let ((inhibit-read-only t))
3714
 
#     (= (process-file-shell-command
3715
 
#         (funcall get-command-line extra)
3716
 
#         nil "*Test*") 0)))
 
3742
#   (let ((process-result
 
3743
#          (let ((inhibit-read-only t))
 
3744
#            (process-file-shell-command
 
3745
#             (funcall get-command-line extra) nil "*Test*"))))
 
3746
#     (and (numberp process-result)
 
3747
#          (= process-result 0))))
3717
3748
# get-command-line:
3718
3749
# (lambda (&optional extra)
3719
3750
#   (let ((quoted-script