28
28
from dbus.mainloop.glib import DBusGMainLoop
32
import logging.handlers
34
# logghandler.setFormatter(logging.Formatter('%(levelname)s %(message)s')
36
logger = logging.Logger('mandos')
37
logger.addHandler(logging.handlers.SysLogHandler(facility = logging.handlers.SysLogHandler.LOG_DAEMON))
31
39
# This variable is used to optionally bind to a specified interface.
32
40
# It is a global variable to fit in with the other variables from the
33
41
# Avahi server example code.
149
157
"""Stop this client.
150
158
The possibility that this client might be restarted is left
151
159
open, but not currently used."""
153
sys.stderr.write(u"Stopping client %s\n" % self.name)
160
logger.debug(u"Stopping client %s", self.name)
154
161
self.secret = None
155
162
if self.stop_initiator_tag:
156
163
gobject.source_remove(self.stop_initiator_tag)
179
186
now = datetime.datetime.now()
180
187
if os.WIFEXITED(condition) \
181
188
and (os.WEXITSTATUS(condition) == 0):
183
sys.stderr.write(u"Checker for %(name)s succeeded\n"
189
logger.debug(u"Checker for %(name)s succeeded",
185
191
self.last_seen = now
186
192
gobject.source_remove(self.stop_initiator_tag)
187
193
self.stop_initiator_tag = gobject.timeout_add\
188
194
(self._timeout_milliseconds,
191
if not os.WIFEXITED(condition):
192
sys.stderr.write(u"Checker for %(name)s crashed?\n"
195
sys.stderr.write(u"Checker for %(name)s failed\n"
196
if not os.WIFEXITED(condition):
197
logger.warning(u"Checker for %(name)s crashed?",
200
logger.debug(u"Checker for %(name)s failed",
198
203
self.checker_callback_tag = None
199
204
def start_checker(self):
200
205
"""Start a new checker subprocess if one is not running.
201
206
If a checker already exists, leave it running and do
203
208
if self.checker is None:
205
sys.stderr.write(u"Starting checker for %s\n"
209
logger.debug(u"Starting checker for %s",
208
212
command = self.check_command % self.fqdn
209
213
except TypeError:
210
214
escaped_attrs = dict((key, re.escape(str(val)))
212
216
vars(self).iteritems())
213
command = self.check_command % escaped_attrs
218
command = self.check_command % escaped_attrs
219
except TypeError, error:
220
logger.critical(u'Could not format string "%s": %s',
221
self.check_command, error)
222
return True # Try again later
215
224
self.checker = subprocess.\
223
232
checker_callback)
224
233
except subprocess.OSError, error:
225
sys.stderr.write(u"Failed to start subprocess: %s\n"
234
logger.error(u"Failed to start subprocess: %s",
227
236
# Re-run this periodically if run by gobject.timeout_add
229
238
def stop_checker(self):
298
307
Note: This will run in its own forked process."""
300
309
def handle(self):
302
sys.stderr.write(u"TCP request came\n")
303
sys.stderr.write(u"Request: %s\n" % self.request)
304
sys.stderr.write(u"Client Address: %s\n"
305
% unicode(self.client_address))
306
sys.stderr.write(u"Server: %s\n" % self.server)
310
logger.debug(u"TCP connection from: %s",
311
unicode(self.client_address))
307
312
session = gnutls.connection.ClientSession(self.request,
308
313
gnutls.connection.\
309
314
X509Credentials())
320
325
session.handshake()
321
326
except gnutls.errors.GNUTLSError, error:
323
sys.stderr.write(u"Handshake failed: %s\n" % error)
327
logger.debug(u"Handshake failed: %s", error)
324
328
# Do not run session.bye() here: the session is not
325
329
# established. Just abandon the request.
328
332
fpr = fingerprint(peer_certificate(session))
329
333
except (TypeError, gnutls.errors.GNUTLSError), error:
331
sys.stderr.write(u"Bad certificate: %s\n" % error)
334
logger.debug(u"Bad certificate: %s", error)
335
sys.stderr.write(u"Fingerprint: %s\n" % fpr)
337
logger.debug(u"Fingerprint: %s", fpr)
337
339
for c in clients:
338
340
if c.fingerprint == fpr:
342
344
# that the client timed out while establishing the GnuTLS
344
346
if (not client) or (not client.still_valid()):
347
sys.stderr.write(u"Client %(name)s is invalid\n"
350
sys.stderr.write(u"Client not found for "
351
u"fingerprint: %s\n" % fpr)
348
logger.debug(u"Client %(name)s is invalid",
351
logger.debug(u"Client not found for fingerprint: %s",
355
356
while sent_size < len(client.secret):
356
357
sent = session.send(client.secret[sent_size:])
358
sys.stderr.write(u"Sent: %d, remaining: %d\n"
359
% (sent, len(client.secret)
360
- (sent_size + sent)))
358
logger.debug(u"Sent: %d, remaining: %d",
359
sent, len(client.secret)
360
- (sent_size + sent))
361
361
sent_size += sent
391
391
self.options.interface)
392
392
except socket.error, error:
393
393
if error[0] == errno.EPERM:
394
sys.stderr.write(u"Warning: No permission to" \
395
u" bind to interface %s\n"
396
% self.options.interface)
394
logger.warning(u"No permission to"
395
u" bind to interface %s",
396
self.options.interface)
399
399
# Only bind(2) the socket if we really need to.
453
453
avahi.DBUS_INTERFACE_ENTRY_GROUP)
454
454
group.connect_to_signal('StateChanged',
455
455
entry_group_state_changed)
457
sys.stderr.write(u"Adding service '%s' of type '%s' ...\n"
458
% (serviceName, serviceType))
456
logger.debug(u"Adding service '%s' of type '%s' ...",
457
serviceName, serviceType)
460
459
group.AddService(
461
460
serviceInterface, # interface
479
478
def server_state_changed(state):
480
479
"""From the Avahi server example code"""
481
480
if state == avahi.SERVER_COLLISION:
482
sys.stderr.write(u"WARNING: Server name collision\n")
481
logger.warning(u"Server name collision")
484
483
elif state == avahi.SERVER_RUNNING:
489
488
"""From the Avahi server example code"""
490
489
global serviceName, server, rename_count
493
sys.stderr.write(u"state change: %i\n" % state)
491
logger.debug(u"state change: %i", state)
495
493
if state == avahi.ENTRY_GROUP_ESTABLISHED:
497
sys.stderr.write(u"Service established.\n")
494
logger.debug(u"Service established.")
498
495
elif state == avahi.ENTRY_GROUP_COLLISION:
500
497
rename_count = rename_count - 1
501
498
if rename_count > 0:
502
499
name = server.GetAlternativeServiceName(name)
503
sys.stderr.write(u"WARNING: Service name collision, "
504
u"changing name to '%s' ...\n" % name)
500
logger.warning(u"Service name collision, "
501
u"changing name to '%s' ...", name)
509
sys.stderr.write(u"ERROR: No suitable service name found "
510
u"after %i retries, exiting.\n"
506
logger.error(u"No suitable service name found "
507
u"after %i retries, exiting.",
513
510
elif state == avahi.ENTRY_GROUP_FAILURE:
514
sys.stderr.write(u"Error in group state changed %s\n"
511
logger.error(u"Error in group state changed %s",
603
600
def remove_from_clients(client):
604
601
clients.remove(client)
607
sys.stderr.write(u"No clients left, exiting\n")
603
logger.debug(u"No clients left, exiting")
610
606
clients.update(Set(Client(name=section, options=options,
622
618
# Find out what random port we got
623
619
servicePort = tcp_server.socket.getsockname()[1]
625
sys.stderr.write(u"Now listening on port %d\n" % servicePort)
620
logger.debug(u"Now listening on port %d", servicePort)
627
622
if options.interface is not None:
628
623
serviceInterface = if_nametoindex(options.interface)