35
32
import logging.handlers
34
# logghandler.setFormatter(logging.Formatter('%(levelname)s %(message)s')
37
36
logger = logging.Logger('mandos')
38
syslogger = logging.handlers.SysLogHandler\
39
(facility = logging.handlers.SysLogHandler.LOG_DAEMON)
40
syslogger.setFormatter(logging.Formatter\
41
('%(levelname)s: %(message)s'))
42
logger.addHandler(syslogger)
37
logger.addHandler(logging.handlers.SysLogHandler(facility = logging.handlers.SysLogHandler.LOG_DAEMON))
45
39
# This variable is used to optionally bind to a specified interface.
46
40
# It is a global variable to fit in with the other variables from the
114
108
del _set_interval
115
109
def __init__(self, name=None, options=None, stop_hook=None,
116
fingerprint=None, secret=None, secfile=None,
117
fqdn=None, timeout=None, interval=-1, checker=None):
110
fingerprint=None, secret=None, secfile=None, fqdn=None,
111
timeout=None, interval=-1, checker=None):
119
113
# Uppercase and remove spaces from fingerprint
120
114
# for later comparison purposes with return value of
133
127
self.created = datetime.datetime.now()
134
128
self.last_seen = None
135
129
if timeout is None:
136
self.timeout = options.timeout
138
self.timeout = string_to_delta(timeout)
130
timeout = options.timeout
131
self.timeout = timeout
139
132
if interval == -1:
140
self.interval = options.interval
133
interval = options.interval
142
self.interval = string_to_delta(interval)
135
interval = string_to_delta(interval)
136
self.interval = interval
143
137
self.stop_hook = stop_hook
144
138
self.checker = None
145
139
self.checker_initiator_tag = None
199
193
self.stop_initiator_tag = gobject.timeout_add\
200
194
(self._timeout_milliseconds,
202
elif not os.WIFEXITED(condition):
196
if not os.WIFEXITED(condition):
203
197
logger.warning(u"Checker for %(name)s crashed?",
222
218
command = self.check_command % escaped_attrs
223
219
except TypeError, error:
224
logger.critical(u'Could not format string "%s":'
225
u' %s', self.check_command, error)
220
logger.critical(u'Could not format string "%s": %s',
221
self.check_command, error)
226
222
return True # Try again later
228
logger.debug(u"Starting checker %r for %s",
230
224
self.checker = subprocess.\
226
stdout=subprocess.PIPE,
232
227
close_fds=True, shell=True,
234
self.checker_callback_tag = gobject.child_watch_add\
236
self.checker_callback)
229
self.checker_callback_tag = gobject.\
230
child_watch_add(self.checker.pid,
237
233
except subprocess.OSError, error:
238
234
logger.error(u"Failed to start subprocess: %s",
279
274
def fingerprint(openpgp):
280
"Convert an OpenPGP data string to a hexdigit fingerprint string"
281
275
# New empty GnuTLS certificate
282
276
crt = gnutls.library.types.gnutls_openpgp_crt_t()
283
277
gnutls.library.functions.gnutls_openpgp_crt_init\
512
logger.error(u"No suitable service name found after %i"
513
u" retries, exiting.", n_rename)
506
logger.error(u"No suitable service name found "
507
u"after %i retries, exiting.",
515
510
elif state == avahi.ENTRY_GROUP_FAILURE:
516
511
logger.error(u"Error in group state changed %s",
521
517
def if_nametoindex(interface):
537
533
return interface_index
540
def daemon(nochdir, noclose):
541
"""See daemon(3). Standard BSD Unix function.
542
This should really exist as os.daemon, but it doesn't (yet)."""
549
# Close all standard open file descriptors
550
null = os.open("/dev/null", os.O_NOCTTY | os.O_RDWR)
551
if not stat.S_ISCHR(os.fstat(null).st_mode):
552
raise OSError(errno.ENODEV,
553
"/dev/null not a character device")
554
os.dup2(null, sys.stdin.fileno())
555
os.dup2(null, sys.stdout.fileno())
556
os.dup2(null, sys.stderr.fileno())
561
def killme(status = 0):
562
logger.debug("Stopping server with exit status %d", status)
564
if main_loop_started:
570
536
if __name__ == '__main__':
572
main_loop_started = False
573
537
parser = OptionParser()
574
538
parser.add_option("-i", "--interface", type="string",
575
539
default=None, metavar="IF",
576
540
help="Bind to interface IF")
541
parser.add_option("--cert", type="string", default="cert.pem",
543
help="Public key certificate PEM file to use")
544
parser.add_option("--key", type="string", default="key.pem",
546
help="Private key PEM file to use")
547
parser.add_option("--ca", type="string", default="ca.pem",
549
help="Certificate Authority certificate PEM file to use")
550
parser.add_option("--crl", type="string", default="crl.pem",
552
help="Certificate Revokation List PEM file to use")
577
553
parser.add_option("-p", "--port", type="int", default=None,
578
554
help="Port number to receive requests on")
579
555
parser.add_option("--timeout", type="string", # Parsed later
604
580
parser.error("option --interval: Unparseable time")
606
582
# Parse config file
607
defaults = { "checker": "fping -q -- %%(fqdn)s" }
583
defaults = { "checker": "sleep 1; fping -q -- %%(fqdn)s" }
608
584
client_config = ConfigParser.SafeConfigParser(defaults)
609
585
#client_config.readfp(open("secrets.conf"), "secrets.conf")
610
586
client_config.read("mandos-clients.conf")
621
597
debug = options.debug
624
console = logging.StreamHandler()
625
# console.setLevel(logging.DEBUG)
626
console.setFormatter(logging.Formatter\
627
('%(levelname)s: %(message)s'))
628
logger.addHandler(console)
632
600
def remove_from_clients(client):
633
601
clients.remove(client)
635
603
logger.debug(u"No clients left, exiting")
638
606
clients.update(Set(Client(name=section, options=options,
639
607
stop_hook = remove_from_clients,
640
608
**(dict(client_config\
641
609
.items(section))))
642
610
for section in client_config.sections()))
648
"Cleanup function; run on exit"
650
# From the Avahi server example code
651
if not group is None:
654
# End of Avahi example code
656
for client in clients:
657
client.stop_hook = None
660
atexit.register(cleanup)
663
signal.signal(signal.SIGINT, signal.SIG_IGN)
664
signal.signal(signal.SIGHUP, lambda signum, frame: killme())
665
signal.signal(signal.SIGTERM, lambda signum, frame: killme())
667
611
for client in clients:
681
625
# From the Avahi server example code
682
626
server.connect_to_signal("StateChanged", server_state_changed)
684
server_state_changed(server.GetState())
685
except dbus.exceptions.DBusException, error:
686
logger.critical(u"DBusException: %s", error)
627
server_state_changed(server.GetState())
688
628
# End of Avahi example code
690
630
gobject.io_add_watch(tcp_server.fileno(), gobject.IO_IN,