/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: 2008-11-08 17:26:35 UTC
  • Revision ID: teddy@fukt.bsnet.se-20081108172635-6eexzbysvsk4bu1z
* mandos: Also import "with_statement" and "absolute_import" from
          "__future__.  Import "closing" from "contextlib".
  (Client.__init__): Use "with closing" on "secfile".
  (Client.checker_callback): Call "self.bump_timeout()" instead of
                             doing it directly.
  (Client.bump_timeout): New method to bump up the timeout.
  (TCP_handler.handle): Simplify code to provide fallback default for
                        GnuTLS priority string.
  (IPv6_TCPServer): Do not inherit from
                    "SocketServer.ForkingTCPServer", since that is
                    undocumented - instead, follow the example code
                    from the documentation.
  (if_nametoindex): Use "with closing" on the socket.

Show diffs side-by-side

added added

removed removed

Lines of Context:
30
30
# Contact the authors at <mandos@fukt.bsnet.se>.
31
31
32
32
 
33
 
from __future__ import division
 
33
from __future__ import division, with_statement, absolute_import
34
34
 
35
35
import SocketServer
36
36
import socket
55
55
import logging
56
56
import logging.handlers
57
57
import pwd
 
58
from contextlib import closing
58
59
 
59
60
import dbus
60
61
import gobject
240
241
        if "secret" in config:
241
242
            self.secret = config["secret"].decode(u"base64")
242
243
        elif "secfile" in config:
243
 
            secfile = open(os.path.expanduser(os.path.expandvars
244
 
                                              (config["secfile"])))
245
 
            self.secret = secfile.read()
246
 
            secfile.close()
 
244
            with closing(open(os.path.expanduser
 
245
                              (os.path.expandvars
 
246
                               (config["secfile"])))) \
 
247
                               as secfile:
 
248
                self.secret = secfile.read()
247
249
        else:
248
250
            raise TypeError(u"No secret or secfile for client %s"
249
251
                            % self.name)
297
299
        self.stop()
298
300
    def checker_callback(self, pid, condition):
299
301
        """The checker has completed, so take appropriate actions."""
300
 
        now = datetime.datetime.now()
301
302
        self.checker_callback_tag = None
302
303
        self.checker = None
303
304
        if os.WIFEXITED(condition) \
304
305
               and (os.WEXITSTATUS(condition) == 0):
305
306
            logger.info(u"Checker for %(name)s succeeded",
306
307
                        vars(self))
307
 
            self.last_checked_ok = now
308
 
            gobject.source_remove(self.stop_initiator_tag)
309
 
            self.stop_initiator_tag = gobject.timeout_add\
310
 
                                      (self._timeout_milliseconds,
311
 
                                       self.stop)
 
308
            self.bump_timeout()
312
309
        elif not os.WIFEXITED(condition):
313
310
            logger.warning(u"Checker for %(name)s crashed?",
314
311
                           vars(self))
315
312
        else:
316
313
            logger.info(u"Checker for %(name)s failed",
317
314
                        vars(self))
 
315
    def bump_timeout(self):
 
316
        """Bump up the timeout for this client.
 
317
        This should only be called when the client has been seen,
 
318
        alive and well.
 
319
        """
 
320
        self.last_checked_ok = datetime.datetime.now()
 
321
        gobject.source_remove(self.stop_initiator_tag)
 
322
        self.stop_initiator_tag = gobject.timeout_add\
 
323
            (self._timeout_milliseconds, self.stop)
318
324
    def start_checker(self):
319
325
        """Start a new checker subprocess if one is not running.
320
326
        If a checker already exists, leave it running and do
447
453
    
448
454
    def handle(self):
449
455
        logger.info(u"TCP connection from: %s",
450
 
                     unicode(self.client_address))
 
456
                    unicode(self.client_address))
451
457
        session = gnutls.connection.ClientSession\
452
458
                  (self.request, gnutls.connection.X509Credentials())
453
459
        
468
474
        #priority = ':'.join(("NONE", "+VERS-TLS1.1", "+AES-256-CBC",
469
475
        #                "+SHA1", "+COMP-NULL", "+CTYPE-OPENPGP",
470
476
        #                "+DHE-DSS"))
471
 
        priority = "NORMAL"             # Fallback default, since this
472
 
                                        # MUST be set.
473
 
        if self.server.settings["priority"]:
474
 
            priority = self.server.settings["priority"]
 
477
        # Use a fallback default, since this MUST be set.
 
478
        priority = self.server.settings.get("priority", "NORMAL")
475
479
        gnutls.library.functions.gnutls_priority_set_direct\
476
480
            (session._c_object, priority, None)
477
481
        
507
511
                           vars(client))
508
512
            session.bye()
509
513
            return
 
514
        ## This won't work here, since we're in a fork.
 
515
        # client.bump_timeout()
510
516
        sent_size = 0
511
517
        while sent_size < len(client.secret):
512
518
            sent = session.send(client.secret[sent_size:])
517
523
        session.bye()
518
524
 
519
525
 
520
 
class IPv6_TCPServer(SocketServer.ForkingTCPServer, object):
 
526
class IPv6_TCPServer(SocketServer.ForkingMixIn,
 
527
                     SocketServer.TCPServer, object):
521
528
    """IPv6 TCP server.  Accepts 'None' as address and/or port.
522
529
    Attributes:
523
530
        settings:       Server settings
652
659
        def if_nametoindex(interface):
653
660
            "Get an interface index the hard way, i.e. using fcntl()"
654
661
            SIOCGIFINDEX = 0x8933  # From /usr/include/linux/sockios.h
655
 
            s = socket.socket()
656
 
            ifreq = fcntl.ioctl(s, SIOCGIFINDEX,
657
 
                                struct.pack("16s16x", interface))
658
 
            s.close()
 
662
            with closing(socket.socket()) as s:
 
663
                ifreq = fcntl.ioctl(s, SIOCGIFINDEX,
 
664
                                    struct.pack("16s16x", interface))
659
665
            interface_index = struct.unpack("I", ifreq[16:20])[0]
660
666
            return interface_index
661
667
    return if_nametoindex(interface)