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