110
110
except AttributeError:
111
111
shlex.quote = re.escape
113
# Add os.set_inheritable if it does not exist
116
except AttributeError:
117
def set_inheritable(fd, inheritable):
118
flags = fcntl.fcntl(fd, fcntl.F_GETFD)
119
if inheritable and ((flags & fcntl.FD_CLOEXEC) != 0):
120
fcntl.fcntl(fd, fcntl.F_SETFL, flags & ~fcntl.FD_CLOEXEC)
121
elif (not inheritable) and ((flags & fcntl.FD_CLOEXEC) == 0):
122
fcntl.fcntl(fd, fcntl.F_SETFL, flags | fcntl.FD_CLOEXEC)
123
os.set_inheritable = set_inheritable
126
113
# Show warnings by default
127
114
if not sys.warnoptions:
156
143
if sys.version_info < (3, 2):
157
144
configparser.Configparser = configparser.SafeConfigParser
160
147
stored_state_file = "clients.pickle"
162
149
log = logging.getLogger(os.path.basename(sys.argv[0]))
974
961
# key_id() and fingerprint() functions
975
962
client["key_id"] = (section.get("key_id", "").upper()
976
963
.replace(" ", ""))
977
client["fingerprint"] = (section.get("fingerprint",
964
client["fingerprint"] = (section["fingerprint"].upper()
979
965
.replace(" ", ""))
980
if not (client["key_id"] or client["fingerprint"]):
981
log.error("Skipping client %s without key_id or"
982
" fingerprint", client_name)
983
del settings[client_name]
985
966
if "secret" in section:
986
967
client["secret"] = codecs.decode(section["secret"]
987
968
.encode("utf-8"),
1092
1074
def __del__(self):
1095
def init_checker(self, randomize_start=False):
1096
# Schedule a new checker to be started a randomly selected
1097
# time (a fraction of 'interval') from now. This spreads out
1098
# the startup of checkers over time when the server is
1077
def init_checker(self):
1078
# Schedule a new checker to be started an 'interval' from now,
1079
# and every interval from then on.
1100
1080
if self.checker_initiator_tag is not None:
1101
1081
GLib.source_remove(self.checker_initiator_tag)
1102
interval_milliseconds = int(self.interval.total_seconds()
1105
delay_milliseconds = random.randrange(
1106
interval_milliseconds + 1)
1108
delay_milliseconds = interval_milliseconds
1109
1082
self.checker_initiator_tag = GLib.timeout_add(
1110
delay_milliseconds, self.start_checker, randomize_start)
1111
delay = datetime.timedelta(0, 0, 0, delay_milliseconds)
1112
# A checker might take up to an 'interval' of time, so we can
1113
# expire at the soonest one interval after a checker was
1114
# started. Since the initial checker is delayed, the expire
1115
# time might have to be extended.
1116
now = datetime.datetime.utcnow()
1117
self.expires = now + delay + self.interval
1118
# Schedule a disable() at expire time
1083
random.randrange(int(self.interval.total_seconds() * 1000
1086
# Schedule a disable() when 'timeout' has passed
1119
1087
if self.disable_initiator_tag is not None:
1120
1088
GLib.source_remove(self.disable_initiator_tag)
1121
1089
self.disable_initiator_tag = GLib.timeout_add(
1122
int((self.expires - now).total_seconds() * 1000),
1090
int(self.timeout.total_seconds() * 1000), self.disable)
1091
# Also start a new checker *right now*.
1092
self.start_checker()
1125
1094
def checker_callback(self, source, condition, connection,
1169
1138
def need_approval(self):
1170
1139
self.last_approval_request = datetime.datetime.utcnow()
1172
def start_checker(self, start_was_randomized=False):
1141
def start_checker(self):
1173
1142
"""Start a new checker subprocess if one is not running.
1175
1144
If a checker already exists, leave it running and do
1225
1194
GLib.IOChannel.unix_new(pipe[0].fileno()),
1226
1195
GLib.PRIORITY_DEFAULT, GLib.IO_IN,
1227
1196
self.checker_callback, pipe[0], command)
1228
if start_was_randomized:
1229
# We were started after a random delay; Schedule a new
1230
# checker to be started an 'interval' from now, and every
1231
# interval from then on.
1232
now = datetime.datetime.utcnow()
1233
self.checker_initiator_tag = GLib.timeout_add(
1234
int(self.interval.total_seconds() * 1000),
1236
self.expires = max(self.expires, now + self.interval)
1237
# Don't start a new checker again after same random delay
1239
1197
# Re-run this periodically if run by GLib.timeout_add
3109
3067
# Later, stdin will, and stdout and stderr might, be dup'ed
3110
3068
# over with an opened os.devnull. But we don't want this to
3111
3069
# happen with a supplied network socket.
3112
while 0 <= server_settings["socket"] <= 2:
3070
if 0 <= server_settings["socket"] <= 2:
3113
3071
server_settings["socket"] = os.dup(server_settings
3115
os.set_inheritable(server_settings["socket"], False)
3116
3073
del server_config
3118
3075
# Override the settings from the config file with command line