Source code for pyptlib.server_config
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
Low-level parts of pyptlib that are only useful to servers.
"""
import pyptlib.config as config
[docs]class ServerConfig(config.Config):
    """
    A client-side pyptlib configuration.
    :var tuple ORPort: (ip,port) pointing to Tor's ORPort.
    :var tuple extendedORPort: (ip,port) pointing to Tor's Extended ORPort. None if Extended ORPort is not supported.
    :var dict serverBindAddr: A dictionary {<transport> : [<addr>, <port>]}, where <transport> is the name of the transport that must be spawned, and [<addr>, <port>] is a list containing the location where that transport should bind. The dictionary can be empty.
    :var string authCookieFile: String representing the filesystem path where the Extended ORPort Authentication cookie is stored. None if Extended ORPort authentication is not supported.
    :raises: :class:`pyptlib.config.EnvError` if environment was incomplete or corrupted.
    """
    def __init__(self):
        config.Config.__init__(self)
        """
        TOR_PT_EXTENDED_SERVER_PORT is optional; tor uses the empty
        string as its value if it does not support the Extended
        ORPort.
        """
        ext_orport_tmp = self.get('TOR_PT_EXTENDED_SERVER_PORT')
        if ext_orport_tmp == '':
            self.extendedORPort = None
        else:
            self.extendedORPort = self.get_addrport('TOR_PT_EXTENDED_SERVER_PORT')
        if self.check('TOR_PT_AUTH_COOKIE_FILE'):
            self.authCookieFile = self.get('TOR_PT_AUTH_COOKIE_FILE')
        else:
            self.authCookieFile = None
        # Check that either both Extended ORPort and the Extended
        # ORPort Authentication Cookie are present, or none.
        if self.extendedORPort and not self.authCookieFile:
            raise config.EnvError("Extended ORPort address provided, but no cookie file.")
        elif self.authCookieFile and not self.extendedORPort:
            raise config.EnvError("Extended ORPort Authentication cookie file provided, but no Extended ORPort address.")
        # Get ORPort.
        self.ORPort = self.get_addrport('TOR_PT_ORPORT')
        # Get bind addresses.
        self.serverBindAddr = {}
        bindaddrs = self.get('TOR_PT_SERVER_BINDADDR').split(',')
        for bindaddr in bindaddrs:
            (transport_name, addrport) = bindaddr.split('-')
            (addr, port) = self.get_addrport_from_string(addrport)
            self.serverBindAddr[transport_name] = (addr, port)
        # Get transports.
        self.transports = self.get('TOR_PT_SERVER_TRANSPORTS').split(',')
        if '*' in self.transports:
            self.allTransportsEnabled = True
            self.transports.remove('*')
        if sorted(self.transports) != sorted(self.serverBindAddr.keys()):
            raise config.EnvError("Can't match transports with bind addresses (%s, %s)" % (self.transports, self.serverBindAddr.keys()))
[docs]    def getExtendedORPort(self):
        """
        :returns: :attr:`pyptlib.server_config.ServerConfig.extendedORPort`
        """
        return self.extendedORPort
 
[docs]    def getORPort(self):
        """
        :returns: :attr:`pyptlib.server_config.ServerConfig.ORPort`
        """
        return self.ORPort
 
[docs]    def getServerBindAddresses(self):
        """
        :returns: :attr:`pyptlib.server_config.ServerConfig.serverBindAddr`
        """
        return self.serverBindAddr
 
[docs]    def getServerTransports(self):
        """
        :returns: :attr:`pyptlib.config.Config.transports`
        """
        return self.transports
 
[docs]    def getAuthCookieFile(self):
        """
        :returns: :attr:`pyptlib.server_config.ServerConfig.authCookieFile`
        """
        return self.authCookieFile
 
[docs]    def writeMethod(self, name, addrport, options):
        """
        Write a message to stdout announcing that a server transport was
        successfully launched.
        :param str name: Name of transport.
        :param tuple addrport: (addr,port) where this transport is listening for connections.
        :param str options: Transport options.
        """
        if options:
            self.emit('SMETHOD %s %s:%s %s' % (name, addrport[0],
                      addrport[1], options))
        else:
            self.emit('SMETHOD %s %s:%s' % (name, addrport[0],
                      addrport[1]))
 
[docs]    def writeMethodError(self, name, message):  # SMETHOD-ERROR
        """
        Write a message to stdout announcing that we failed to launch
        a transport.
        :param str name: Name of transport.
        :param str message: Error message.
        """
        self.emit('SMETHOD-ERROR %s %s' % (name, message))
 
[docs]    def writeMethodEnd(self):  # SMETHODS DONE
        """
        Write a message to stdout announcing that we finished
        launching transports..
        """
        self.emit('SMETHODS DONE')
 
[docs]    def get_addrport(self, key):
        """
        Parse an environment variable holding an address:port value.
        :param str key: Environment variable key.
        :returns: tuple -- (address,port)
        :raises: :class:`pyptlib.config.EnvError` if string was not in address:port format.
        """
        string = self.get(key)
        return self.get_addrport_from_string(string)
 
[docs]    def get_addrport_from_string(self, string):
        """
        Parse a string holding an address:port value.
        :param str string: A string.
        :returns: tuple -- (address,port)
        :raises: :class:`pyptlib.config.EnvError` if string was not in address:port format.
        """
        addrport = string.split(':')
        if (len(addrport) != 2) or (not addrport[1].isdigit()):
            message = 'Parsing error (%s).' % (string)
            self.writeEnvError(message)
            raise config.EnvError(message) # XXX maybe return ValueError
        if (not 0 <= int(addrport[1]) < 65536):
            message = 'Port out of range (%s).' % (string)
            self.writeEnvError(message)
            raise config.EnvError(message)
        return addrport