Beispiel #1
0
 def __init__(
     self,
     url,
     method="GET",
     postdata=None,
     headers=None,
     agent="Twisted PageGetter",
     timeout=0,
     cookies=None,
     followRedirect=1,
 ):
     self.protocol.followRedirect = followRedirect
     self.timeout = timeout
     self.agent = agent
     if cookies is None:
         cookies = {}
     self.cookies = cookies
     if headers is not None:
         self.headers = InsensitiveDict(headers)
     else:
         self.headers = InsensitiveDict()
     if postdata is not None:
         self.headers.setdefault("Content-Length", len(postdata))
         self.headers.setdefault("connection", "close")
     self.postdata = postdata
     self.method = method
     self.setURL(url)
     self.waiting = 1
     self.deferred = defer.Deferred()
     self.response_headers = None
Beispiel #2
0
    def __init__(self,
                 tagName,
                 attributes=None,
                 parentNode=None,
                 filename=None,
                 markpos=None,
                 case_insensitive=1,
                 namespace=None):
        Node.__init__(self, parentNode)
        preserve_case = not case_insensitive
        tagName = tagName if preserve_case else tagName.lower()
        unescaped = unescape_dict(attributes or {})

        if case_insensitive:
            self.attributes = InsensitiveDict(unescaped,
                                              preserve=preserve_case)
        else:
            self.attributes = unescaped

        self.preserve_case = not case_insensitive
        self.case_insensitive = case_insensitive
        self.endTagName = self.nodeName = self.tagName = tagName
        self._filename = filename
        self._markpos = markpos
        self.namespace = namespace
        self.tag_is_blockelement = tagName in self.BLOCKELEMENTS
        self.tag_is_nice_format = tagName in self.NICEFORMATS
        self.tag_is_singleton = tagName.lower() in self.SINGLETONS
Beispiel #3
0
    def __init__(self,
                 url,
                 method='GET',
                 postdata=None,
                 headers=None,
                 agent="Twisted PageGetter",
                 timeout=0,
                 cookies=None,
                 followRedirect=1):
        self.protocol.followRedirect = followRedirect
        self.timeout = timeout
        self.agent = agent

        if cookies is None:
            cookies = {}
        self.cookies = cookies
        if headers is not None:
            self.headers = InsensitiveDict(headers)
        else:
            self.headers = InsensitiveDict()
        if postdata is not None:
            self.headers.setdefault('Content-Length', len(postdata))
            # just in case a broken http/1.1 decides to keep connection alive
            self.headers.setdefault("connection", "close")
        self.postdata = postdata
        self.method = method

        self.setURL(url)

        self.waiting = 1
        self.deferred = defer.Deferred()
        self.response_headers = None
Beispiel #4
0
    def __init__(self,
                 tagName,
                 attributes=None,
                 parentNode=None,
                 filename=None,
                 markpos=None,
                 caseInsensitive=1,
                 preserveCase=0,
                 namespace=None):
        Node.__init__(self, parentNode)
        self.preserveCase = preserveCase or not caseInsensitive
        self.caseInsensitive = caseInsensitive
        if not preserveCase:
            tagName = tagName.lower()
        if attributes is None:
            self.attributes = {}
        else:
            self.attributes = attributes
            for k, v in self.attributes.items():
                self.attributes[k] = unescape(v)

        if caseInsensitive:
            self.attributes = InsensitiveDict(self.attributes,
                                              preserve=preserveCase)

        self.endTagName = self.nodeName = self.tagName = tagName
        self._filename = filename
        self._markpos = markpos
        self.namespace = namespace
Beispiel #5
0
    def __init__(self, url, method='GET', postdata=None, headers=None,
                 agent="Twisted PageGetter", timeout=0, cookies=None,
                 followRedirect=True, redirectLimit=20,
                 afterFoundGet=False):
        self.followRedirect = followRedirect
        self.redirectLimit = redirectLimit
        self._redirectCount = 0
        self.timeout = timeout
        self.agent = agent
        self.afterFoundGet = afterFoundGet
        if cookies is None:
            cookies = {}
        self.cookies = cookies
        if headers is not None:
            self.headers = InsensitiveDict(headers)
        else:
            self.headers = InsensitiveDict()
        if postdata is not None:
            self.headers.setdefault('Content-Length', len(postdata))
            # just in case a broken http/1.1 decides to keep connection alive
            self.headers.setdefault("connection", "close")
        self.postdata = postdata
        self.method = method

        self.setURL(url)

        self.waiting = 1
        self._disconnectedDeferred = defer.Deferred()
        self.deferred = defer.Deferred()
        # Make sure the first callback on the result Deferred pauses the
        # callback chain until the request connection is closed.
        self.deferred.addBoth(self._waitForDisconnect)
        self.response_headers = None
Beispiel #6
0
    def __init__(self, url, method='GET', postdata=None, headers=None,
                 agent="Twisted PageGetter", timeout=0, cookies=None,
                 followRedirect=1, proxy=None):
        self.protocol.followRedirect = followRedirect
        self.timeout = timeout
        self.agent = agent
        self.proxy = proxy

        if cookies is None:
            cookies = {}
        self.cookies = cookies
        if headers is not None:
            self.headers = InsensitiveDict(headers)
        else:
            self.headers = InsensitiveDict()
        if postdata is not None:
            self.headers.setdefault('Content-Length', len(postdata))
            # just in case a broken http/1.1 decides to keep connection alive
            self.headers.setdefault("connection", "close")
        self.postdata = postdata
        self.method = method

        self.setURL(url)

        self.waiting = 1
        self.deferred = defer.Deferred()
        self.response_headers = None
Beispiel #7
0
 def __init__(self, initial=None, case_mapping=None):
     if case_mapping is None:
         case_mapping = CaseMapping.by_name("rfc1459")
     elif isinstance(case_mapping, basestring):
         case_mapping = CaseMapping.by_name(case_mapping)
     self.case_mapping = case_mapping
     InsensitiveDict.__init__(self, initial, preserve=1)
Beispiel #8
0
class RestClientFactory(protocol.ClientFactory):

    protocol = client.HTTPPageGetter
    noisy = False
    
    def __init__(self, host, port, path, data, timeout = 60):
        self.log = log.getChild('ClientFactory')
        self.timeout = timeout
        self.agent = "RestClient"
        self.headers = InsensitiveDict()
        self.headers.setdefault('Content-Length', len(data))
        self.headers.setdefault("connection", "close")
        self.method = 'POST'
        self.url = 'http://' + host + ':' + str(port) + path
        self.scheme = 'http'
        self.postdata = data
        self.host = host
        self.port = port
        self.path = path
        self.waiting = 1
        self.deferred = defer.Deferred()
        self.response_headers = None
        self.cookies = {}

    def __repr__(self):
        return "<%s: %s>" % (self.__class__.__name__, self.url)

    def buildProtocol(self, addr):
        p = protocol.ClientFactory.buildProtocol(self, addr)
        if self.timeout:
            timeoutCall = reactor.callLater(self.timeout, p.timeout)
            self.deferred.addBoth(self._cancelTimeout, timeoutCall)
        return p

    def _cancelTimeout(self, result, timeoutCall):
        if timeoutCall.active():
            timeoutCall.cancel()
        return result

    def gotHeaders(self, headers):
        self.response_headers = headers
        
    def gotStatus(self, version, status):
        self.version, self.status = version, status

    def page(self, page):
        if self.waiting:
            self.waiting = 0
            self.deferred.callback(page)

    def noPage(self, reason):
        if self.waiting:
            self.waiting = 0
            self.deferred.errback(reason)

    def clientConnectionFailed(self, _, reason):
        if self.waiting:
            self.waiting = 0
            self.deferred.errback(reason)
Beispiel #9
0
class RestClientFactory(protocol.ClientFactory):

    protocol = client.HTTPPageGetter
    noisy = False

    def __init__(self, host, port, path, data, timeout=60):
        self.timeout = timeout
        self.agent = "RestClient"
        self.headers = InsensitiveDict()
        self.headers.setdefault('Content-Length', len(data))
        self.headers.setdefault("connection", "close")
        self.method = 'POST'
        self.url = 'http://' + host + ':' + str(port) + path
        self.scheme = 'http'
        self.postdata = data
        self.host = host
        self.port = port
        self.path = path
        self.waiting = 1
        self.deferred = defer.Deferred()
        self.response_headers = None
        self.cookies = {}

    def __repr__(self):
        return "<%s: %s>" % (self.__class__.__name__, self.url)

    def buildProtocol(self, addr):
        p = protocol.ClientFactory.buildProtocol(self, addr)
        if self.timeout:
            timeoutCall = reactor.callLater(self.timeout, p.timeout)
            self.deferred.addBoth(self._cancelTimeout, timeoutCall)
        return p

    def _cancelTimeout(self, result, timeoutCall):
        if timeoutCall.active():
            timeoutCall.cancel()
        return result

    def gotHeaders(self, headers):
        self.response_headers = headers

    def gotStatus(self, version, status, message):
        self.version, self.status, self.message = version, status, message

    def page(self, page):
        if self.waiting:
            self.waiting = 0
            self.deferred.callback(page)

    def noPage(self, reason):
        if self.waiting:
            self.waiting = 0
            self.deferred.errback(reason)

    def clientConnectionFailed(self, _, reason):
        if self.waiting:
            self.waiting = 0
            self.deferred.errback(reason)
Beispiel #10
0
class HeaderAwareHTTPClientFactory(client.HTTPClientFactory):

    protocol = myHTTPPageGetter
    noisy = False

    def __init__(self,
                 url,
                 method='GET',
                 postdata=None,
                 headers=None,
                 agent="Twisted PageGetter",
                 timeout=0,
                 cookies=None,
                 followRedirect=True,
                 redirectLimit=20):
        self.followRedirect = followRedirect
        self.redirectLimit = redirectLimit
        self._redirectCount = 0
        self.timeout = timeout
        self.agent = agent

        if cookies is None:
            cookies = {}
        self.cookies = cookies
        if headers is not None:
            self.headers = InsensitiveDict(headers)
        else:
            self.headers = InsensitiveDict()
        if postdata is not None:
            self.headers.setdefault('Content-Length', len(postdata))
            # just in case a broken http/1.1 decides to keep connection alive
            self.headers.setdefault("connection", "close")
        self.postdata = postdata
        self.method = method

        self.setURL(url)

        self.waiting = 1
        self.deferred = defer.Deferred()
        self.response_headers = None

    def buildProtocol(self, addr):
        p = protocol.ClientFactory.buildProtocol(self, addr)
        p.method = self.method
        p.followRedirect = self.followRedirect
        if self.timeout:
            timeoutCall = reactor.callLater(self.timeout, p.timeout)
            self.deferred.addBoth(self._cancelTimeout, timeoutCall)
        return p

    def page(self, page):
        if self.waiting:
            self.waiting = 0
            self.deferred.callback((page, self.response_headers))
Beispiel #11
0
class HeaderAwareHTTPClientFactory(client.HTTPClientFactory):

    protocol = yourHTTPPageGetter
    noisy = False

    def __init__(self, url, method='GET', postdata=None, headers=None,
                 agent="Coherence PageGetter", timeout=0, cookies=None,
                 followRedirect=True, redirectLimit=20):
        self.followRedirect = followRedirect
        self.redirectLimit = redirectLimit
        self._redirectCount = 0
        self.timeout = timeout
        self.agent = agent

        if cookies is None:
            cookies = {}
        self.cookies = cookies
        if headers is not None:
            self.headers = InsensitiveDict(headers)
        else:
            self.headers = InsensitiveDict()
        if postdata is not None:
            self.headers.setdefault('Content-Length', len(postdata))
            # just in case a broken http/1.1 decides to keep connection alive
            self.headers.setdefault("connection", "close")
        self.postdata = postdata
        self.method = method

        self.setURL(url)

        self.waiting = 1
        self.deferred = defer.Deferred()
        self._disconnectedDeferred = defer.Deferred()
        self.response_headers = None

    def buildProtocol(self, addr):
        p = protocol.ClientFactory.buildProtocol(self, addr)
        p.method = self.method
        p.followRedirect = self.followRedirect
        if self.timeout:
            timeoutCall = reactor.callLater(self.timeout, p.timeout)
            self.deferred.addBoth(self._cancelTimeout, timeoutCall)
            self._disconnectedDeferred = defer.Deferred()
        return p

    def page(self, page):
        if self.waiting:
            self.waiting = 0
            self.deferred.callback((page, self.response_headers))
Beispiel #12
0
    def __init__(self, factory, parent):
        self.factory     = factory
        self.nickname    = parent.nickname.encode('ascii')
        self.realname    = parent.realname.encode('ascii')
        self.username    = parent.ident.encode('ascii')
        self.ns_username = parent.username
        self.ns_password = parent.password
        self.password    = parent.server_password.encode('ascii')
        self.join_channels = parent.channel_map.keys()

        self.users        = InsensitiveDict()
        self.channels     = InsensitiveDict()
        self.cap_requests = set()

        self.parent = parent
Beispiel #13
0
def setIndexLink(template, indexFilename):
    """
    Insert a link to an index document.

    Any node with a C{class} attribute set to C{index-link} will have its tag
    name changed to C{a} and its C{href} attribute set to C{indexFilename}.

    @type template: A DOM Node or Document
    @param template: The output template which defines the presentation of the
    version information.

    @type indexFilename: C{str}
    @param indexFilename: The address of the index document to which to link.
    If any C{False} value, this function will remove all index-link nodes.

    @return: C{None}
    """
    indexLinks = domhelpers.findElementsWithAttribute(template,
                                                      "class",
                                                      "index-link")
    for link in indexLinks:
        if indexFilename is None:
            link.parentNode.removeChild(link)
        else:
            link.nodeName = link.tagName = link.endTagName = 'a'
            link.attributes = InsensitiveDict({'href': indexFilename})
Beispiel #14
0
 def __init__(self, host, port, path, data, timeout = 60):
     self.timeout = timeout
     self.agent = "RestClient"
     self.headers = InsensitiveDict()
     self.headers.setdefault('Content-Length', len(data))
     self.headers.setdefault("connection", "close")
     self.method = 'POST'
     self.url = 'http://' + host + ':' + str(port) + path
     self.postdata = data
     self.host = host
     self.port = port
     self.path = path
     self.waiting = 1
     self.deferred = defer.Deferred()
     self.response_headers = None
     self.cookies = {}
Beispiel #15
0
    def getChild(self, path, request):
        """
        If this L{File}"s path refers to a directory, return a L{File}
        referring to the file named C{path} in that directory.

        If C{path} is the empty string, return a L{DirectoryLister}
        instead.

        @param path: The current path segment.
        @type path: L{bytes}

        @param request: The incoming request.
        @type request: An that provides L{twisted.web.iweb.IRequest}.

        @return: A resource representing the requested file or
            directory, or L{NoResource} if the path cannot be
            accessed.
        @rtype: An object that provides L{resource.IResource}.
        """
        if isinstance(path, bytes):
            try:
                # Request calls urllib.unquote on each path segment,
                # leaving us with raw bytes.
                path = path.decode('utf-8')
            except UnicodeDecodeError:
                log.err(
                    None,
                    "Could not decode path segment as utf-8: %r" % (path, ))
                return self.childNotFound

        self.restat(reraise=False)

        if not self.isdir():
            return self.childNotFound

        if path:
            try:
                fpath = self.child(path)
            except filepath.InsecurePath:
                return self.childNotFound
        else:
            fpath = self.childSearchPreauth(*self.indexNames)
            if fpath is None:
                return self.directoryListing()

        if not fpath.exists():
            fpath = fpath.siblingExtensionSearch(*self.ignoredExts)
            if fpath is None:
                return self.childNotFound

        extension = fpath.splitext()[1]
        if platformType == "win32":
            # don't want .RPY to be different than .rpy, since that would allow
            # source disclosure.
            processor = InsensitiveDict(self.processors).get(extension)
        else:
            processor = self.processors.get(extension)
        if processor:
            return resource.IResource(processor(fpath.path, self.registry))
        return self.createSimilarFile(fpath.path)
    def getChild(self, path, request):
        """See twisted.web.Resource.getChild.
        """
        self.restat()

        if not self.isdir():
            return self.childNotFound

        if path:
            fpath = self.child(path)
        else:
            fpath = self.childSearchPreauth(*self.indexNames)
            if fpath is None:
                return self.directoryListing()

        if not fpath.exists():
            fpath = fpath.siblingExtensionSearch(*self.ignoredExts)
            if fpath is None:
                return self.childNotFound

        if platformType == "win32":
            # don't want .RPY to be different than .rpy, since that would allow
            # source disclosure.
            processor = InsensitiveDict(self.processors).get(
                fpath.splitext()[1])
        else:
            processor = self.processors.get(fpath.splitext()[1])
        if processor:
            return resource.IResource(processor(fpath.path, self.registry))
        return self.createSimilarFile(fpath.path)
Beispiel #17
0
    def __init__(self, tagName, attributes=None, parentNode=None,
                        filename=None, markpos=None,
                        caseInsensitive=1, preserveCase=0,
                 namespace='', escapeAttributes=1):
        Node.__init__(self, parentNode)
        self.preserveCase = preserveCase or not caseInsensitive
        self.caseInsensitive = caseInsensitive
        if not preserveCase:
            tagName = tagName.lower()
        if attributes is None:
            self.attributes = {}
        else:
            self.attributes = attributes
            if escapeAttributes:
                for k, v in self.attributes.items():
                    self.attributes[k] = unescape(v)

        if caseInsensitive:
            self.attributes = InsensitiveDict(self.attributes, 
                                              preserve=preserveCase)

        self.endTagName = self.nodeName = self.tagName = tagName
        self._filename = filename
        self._markpos = markpos
        self.namespace = namespace
Beispiel #18
0
    def __init__(self, factory, plugin):
        self.factory = factory
        self.nickname = plugin.nickname.encode('ascii')
        self.realname = plugin.realname.encode('ascii')
        self.username = plugin.ident.encode('ascii')
        self.ns_username = plugin.username
        self.ns_password = plugin.password
        self.password = plugin.server_password.encode('ascii')
        self.channel = plugin.channel.encode('ascii')
        self.console = plugin.console
        self.irc_message = plugin.irc_message
        self.irc_action = plugin.irc_action
        self.irc_chat_status = plugin.irc_chat_status
        self.mangle_username = plugin.mangle_username

        self.users = InsensitiveDict()
        self.cap_requests = set()
Beispiel #19
0
    def __init__(self,
                 url,
                 method='GET',
                 postdata=None,
                 headers=None,
                 agent="Twisted PageGetter",
                 timeout=0,
                 cookies=None,
                 followRedirect=True,
                 redirectLimit=20):
        self.followRedirect = followRedirect
        self.redirectLimit = redirectLimit
        self._redirectCount = 0
        self.timeout = timeout
        self.agent = agent

        if cookies is None:
            cookies = {}
        self.cookies = cookies
        if headers is not None:
            self.headers = InsensitiveDict(headers)
        else:
            self.headers = InsensitiveDict()
        if postdata is not None:
            self.headers.setdefault('Content-Length', len(postdata))
            # just in case a broken http/1.1 decides to keep connection alive
            self.headers.setdefault("connection", "close")
        self.postdata = postdata
        self.method = method

        self.setURL(url)

        #print( 'method: {}\nurl:{}\nheaders:{}\npostdata:{}'.format( method, url, self.headers, postdata ) )
        self.waiting = 1
        # Fixes Twisted 11.1.0+ support as HTTPClientFactory is expected
        # to have _disconnectedDeferred. See Twisted r32329.
        # As Scrapy implements it's own logic to handle redirects is not
        # needed to add the callback _waitForDisconnect.
        # Specifically this avoids the AttributeError exception when
        # clientConnectionFailed method is called.
        self._disconnectedDeferred = defer.Deferred()
        self.deferred = defer.Deferred()
        self.response_headers = None
Beispiel #20
0
 def __init__(self, factory, plugin):
     self.factory     = factory
     self.nickname    = plugin.nickname.encode('ascii')
     self.realname    = plugin.realname.encode('ascii')
     self.username    = plugin.username.encode('ascii')
     self.ns_password = plugin.password
     self.password    = plugin.server_password.encode('ascii')
     self.channel     = plugin.channel.encode('ascii')
     self.console     = plugin.console
     self.irc_message = plugin.irc_message
     self.users       = InsensitiveDict()
 def test01_proxy(self):
       data = '{"type": "PacketPing"}'
       headers = InsensitiveDict()
       headers.setdefault('Content-Length', len(data))
       headers.setdefault("connection", "close")
       headers.setdefault("proxy-connection", "foo")
       host = '127.0.0.1'
       port = 19481
       path = '/POKER_REST'
       factory = pokerrestclient.PokerProxyClientFactory('POST', path, '1.1', headers, data, MockRequest(), 6, host + ':' + str(port) + path)
       reactor.connectTCP(host, port, factory)
       factory.deferred.addCallback(self.assertNotEquals, None)
       return factory.deferred
Beispiel #22
0
    def __init__(self, dn, attributes={}):
        """

        Initialize the object.

        @param dn: Distinguished Name of the object, as a string.

        @param attributes: Attributes of the object. A dictionary of
        attribute types to list of attribute values.

        """
        self._attributes = InsensitiveDict()
        self.dn = distinguishedname.DistinguishedName(dn)

        for k, vs in attributes.items():
            if k not in self._attributes:
                self._attributes[k] = []
            self._attributes[k].extend(vs)

        for k, vs in self._attributes.items():
            self._attributes[k] = self.buildAttributeSet(k, vs)
Beispiel #23
0
    def __init__(self,
                 url,
                 method='GET',
                 postdata=None,
                 headers=None,
                 agent="Twisted PageGetter",
                 timeout=0,
                 cookies=None,
                 followRedirect=True,
                 redirectLimit=20,
                 afterFoundGet=False):
        self.followRedirect = followRedirect
        self.redirectLimit = redirectLimit
        self._redirectCount = 0
        self.timeout = timeout
        self.agent = agent
        self.afterFoundGet = afterFoundGet
        if cookies is None:
            cookies = {}
        self.cookies = cookies
        if headers is not None:
            self.headers = InsensitiveDict(headers)
        else:
            self.headers = InsensitiveDict()
        if postdata is not None:
            self.headers.setdefault('Content-Length', len(postdata))
            # just in case a broken http/1.1 decides to keep connection alive
            self.headers.setdefault("connection", "close")
        self.postdata = postdata
        self.method = method

        self.setURL(url)

        self.waiting = 1
        self._disconnectedDeferred = defer.Deferred()
        self.deferred = defer.Deferred()
        # Make sure the first callback on the result Deferred pauses the
        # callback chain until the request connection is closed.
        self.deferred.addBoth(self._waitForDisconnect)
        self.response_headers = None
Beispiel #24
0
    def __init__(
        self,
        url,
        method="GET",
        postdata=None,
        headers=None,
        agent="Twisted PageGetter",
        timeout=0,
        cookies=None,
        followRedirect=True,
        redirectLimit=20,
        afterFoundGet=False,
    ):
        self.followRedirect = followRedirect
        self.redirectLimit = redirectLimit
        self._redirectCount = 0
        self.timeout = timeout
        self.agent = agent
        self.afterFoundGet = afterFoundGet
        if cookies is None:
            cookies = {}
        self.cookies = cookies
        if headers is not None:
            self.headers = InsensitiveDict(headers)
        else:
            self.headers = InsensitiveDict()
        if postdata is not None:
            self.headers.setdefault("Content-Length", len(postdata))
            # just in case a broken http/1.1 decides to keep connection alive
            self.headers.setdefault("connection", "close")
        self.postdata = postdata
        self.method = method

        self.setURL(url)

        self.waiting = 1
        self.deferred = defer.Deferred()
        self.response_headers = None
 def __init__(self, host, port, path, data, timeout = 60):
     self.timeout = timeout
     self.agent = "RestClient"
     self.headers = InsensitiveDict()
     self.headers.setdefault('Content-Length', len(data))
     self.headers.setdefault("connection", "close")
     self.method = 'POST'
     self.url = 'http://' + host + ':' + str(port) + path
     self.postdata = data
     self.host = host
     self.port = port
     self.path = path
     self.waiting = 1
     self.deferred = defer.Deferred()
     self.response_headers = None
     self.cookies = {}
Beispiel #26
0
    def __init__(self, headers):
        self.expires = None
        self.mtime = None
        self.length = 0
        self.start = 0
        self.size = 0
        self.mimeType = None

        headers = InsensitiveDict(headers)

        encoding = headers.get("Transfer-Encoding", None)
        if encoding == 'chunked':
            raise errors.FlumotionError("Chunked transfer not supported")

        expires = headers.get("Expires", None)
        if expires is not None:
            try:
                self.expires = http.stringToDatetime(expires)
            except:
                self.expires = 0

        lastmod = headers.get("Last-Modified", None)
        if lastmod is not None:
            self.mtime = http.stringToDatetime(lastmod)

        range = headers.get("Content-Range", None)
        length = headers.get("Content-Length", None)
        if range is not None:
            start, end, total = http.parseContentRange(range)
            self.start = start
            self.length = total
            if length is not None:
                self.size = int(length)
            else:
                self.size = end - start
        elif length is not None:
            self.length = int(length)
            self.size = int(length)
        else:
            raise errors.FlumotionError("Can't get length/size from headers",
                                        headers)

        ctype = headers.get("Content-Type", None)
        if ctype is not None:
            self.mimeType, _pdict = cgi.parse_header(ctype)
Beispiel #27
0
    def __init__(self, factory, plugin):
        self.factory     = factory
        self.nickname    = plugin.nickname.encode('ascii')
        self.realname    = plugin.realname.encode('ascii')
        self.username    = plugin.ident.encode('ascii')
        self.ns_username = plugin.username
        self.ns_password = plugin.password
        self.password    = plugin.server_password.encode('ascii')
        self.channel     = plugin.channel.encode('ascii')
        self.console     = plugin.console
        self.irc_message = plugin.irc_message
        self.irc_action  = plugin.irc_action
        self.irc_chat_status = plugin.irc_chat_status
        self.mangle_username = plugin.mangle_username

        self.users       = InsensitiveDict()
        self.cap_requests = set()
 def __init__(self, host, port, path, data, timeout=60):
     self.timeout = timeout
     self.agent = "RestClient"
     self.headers = InsensitiveDict()
     self.headers.setdefault("Content-Length", len(data))
     self.headers.setdefault("connection", "close")
     self.method = "POST"
     self.url = "http://" + host + ":" + str(port) + path
     self.scheme = "http"
     self.postdata = data
     self.host = host
     self.port = port
     self.path = path
     self.waiting = 1
     self.deferred = defer.Deferred()
     self.response_headers = None
     self.cookies = {}
     self._disconnectedDeferred = defer.Deferred()
Beispiel #29
0
    def __init__(self, headers):
        self.expires = None
        self.mtime = None
        self.length = 0
        self.start = 0
        self.size = 0
        self.mimeType = None

        headers = InsensitiveDict(headers)

        encoding = headers.get("Transfer-Encoding", None)
        if encoding == 'chunked':
            raise errors.FlumotionError("Chunked transfer not supported")

        expires = headers.get("Expires", None)
        if expires is not None:
            try:
                self.expires = http.stringToDatetime(expires)
            except:
                self.expires = 0

        lastmod = headers.get("Last-Modified", None)
        if lastmod is not None:
            self.mtime = http.stringToDatetime(lastmod)

        range = headers.get("Content-Range", None)
        length = headers.get("Content-Length", None)
        if range is not None:
            start, end, total = http.parseContentRange(range)
            self.start = start
            self.length = total
            if length is not None:
                self.size = int(length)
            else:
                self.size = end - start
        elif length is not None:
            self.length = int(length)
            self.size = int(length)
        else:
            raise errors.FlumotionError("Can't get length/size from headers",
                                        headers)

        ctype = headers.get("Content-Type", None)
        if ctype is not None:
            self.mimeType, _pdict = cgi.parse_header(ctype)
Beispiel #30
0
    def locateChild(self, ctx, segments):
        r = self.children.get(segments[0], None)
        if r:
            return r, segments[1:]

        path = segments[0]

        self.fp.restat()

        if not self.fp.isdir():
            return rend.NotFound

        if path:
            fpath = self.fp.child(path)
        else:
            fpath = self.fp.childSearchPreauth(*self.indexNames)
            if fpath is None:
                if self.allowListing:
                    return self.directoryListing(), segments[1:]
                else:
                    return rend.NotFound

        if not fpath.exists():
            fpath = fpath.siblingExtensionSearch(*self.ignoredExts)
            if fpath is None:
                return rend.NotFound

        # Don't run processors on directories - if someone wants their own
        # customized directory rendering, subclass File instead.
        if fpath.isfile():
            if platformType == "win32":
                # don't want .RPY to be different than .rpy, since that
                # would allow source disclosure.
                processor = InsensitiveDict(self.processors).get(
                    fpath.splitext()[1])
            else:
                processor = self.processors.get(fpath.splitext()[1])
            if processor:
                return (inevow.IResource(processor(fpath.path, self.registry)),
                        segments[1:])

        return self.createSimilarFile(fpath.path), segments[1:]
Beispiel #31
0
    def __init__(self, dn, attributes={}):
        """

        Initialize the object.

        @param dn: Distinguished Name of the object, as a string.

        @param attributes: Attributes of the object. A dictionary of
        attribute types to list of attribute values.

        """
        self._attributes=InsensitiveDict()
        self.dn = distinguishedname.DistinguishedName(dn)

        for k,vs in attributes.items():
            if k not in self._attributes:
                self._attributes[k] = []
            self._attributes[k].extend(vs)

        for k,vs in self._attributes.items():
            self._attributes[k] = self.buildAttributeSet(k, vs)
Beispiel #32
0
    def __init__(
        self, tagName, attributes=None, parentNode=None, filename=None,
        markpos=None, case_insensitive=1, namespace=None
    ):
        Node.__init__(self, parentNode)
        preserve_case = not case_insensitive
        tagName = tagName if preserve_case else tagName.lower()
        unescaped = unescape_dict(attributes or {})

        if case_insensitive:
            self.attributes = InsensitiveDict(unescaped, preserve=preserve_case)
        else:
            self.attributes = unescaped

        self.preserve_case = not case_insensitive
        self.case_insensitive = case_insensitive
        self.endTagName = self.nodeName = self.tagName = tagName
        self._filename = filename
        self._markpos = markpos
        self.namespace = namespace
        self.tag_is_blockelement = tagName in self.BLOCKELEMENTS
        self.tag_is_nice_format = tagName in self.NICEFORMATS
        self.tag_is_singleton = tagName.lower() in self.SINGLETONS
Beispiel #33
0
    def getChild(self, path, request):
        """
        If this L{File}'s path refers to a directory, return a L{File}
        referring to the file named C{path} in that directory.

        If C{path} is the empty string, return a L{DirectoryLister} instead.
        """
        self.restat(reraise=False)

        if not self.isdir():
            return self.childNotFound

        if path:
            try:
                fpath = self.child(path)
            except filepath.InsecurePath:
                return self.childNotFound
        else:
            fpath = self.childSearchPreauth(*self.indexNames)
            if fpath is None:
                return self.directoryListing()

        if not fpath.exists():
            fpath = fpath.siblingExtensionSearch(*self.ignoredExts)
            if fpath is None:
                return self.childNotFound

        if platformType == "win32":
            # don't want .RPY to be different than .rpy, since that would allow
            # source disclosure.
            processor = InsensitiveDict(self.processors).get(
                fpath.splitext()[1])
        else:
            processor = self.processors.get(fpath.splitext()[1])
        if processor:
            return resource.IResource(processor(fpath.path, self.registry))
        return self.createSimilarFile(fpath.path)
Beispiel #34
0
def index(document, filename, chapterReference):
    """
    Extract index entries from the given document and store them for later use
    and insert named anchors so that the index can link back to those entries.

    Any node with a C{class} attribute set to C{index} is considered an index
    entry.

    @type document: A DOM Node or Document
    @param document: The input document which contains all of the content to be
    presented.

    @type filename: C{str}
    @param filename: A link to the output for the given document which will be
    included in the index to link to any index entry found here.

    @type chapterReference: ???
    @param chapterReference: ???

    @return: C{None}
    """
    entries = domhelpers.findElementsWithAttribute(document, "class", "index")
    if not entries:
        return
    i = 0
    for entry in entries:
        i += 1
        anchor = 'index%02d' % i
        if chapterReference:
            ref = getSectionReference(entry) or chapterReference
        else:
            ref = 'link'
        indexer.addEntry(filename, anchor, entry.attributes['value'], ref)
        # does nodeName even affect anything?
        entry.nodeName = entry.tagName = entry.endTagName = 'a'
        entry.attributes = InsensitiveDict({'name': anchor})
Beispiel #35
0
class Element(Node):

    preserveCase = 0
    caseInsensitive = 1
    nsprefixes = None

    def __init__(self, tagName, attributes=None, parentNode=None,
                 filename=None, markpos=None,
                 caseInsensitive=1, preserveCase=0,
                 namespace=None):
        Node.__init__(self, parentNode)
        self.preserveCase = preserveCase or not caseInsensitive
        self.caseInsensitive = caseInsensitive
        if not preserveCase:
            tagName = tagName.lower()
        if attributes is None:
            self.attributes = {}
        else:
            self.attributes = attributes
            for k, v in self.attributes.items():
                self.attributes[k] = unescape(v)

        if caseInsensitive:
            self.attributes = InsensitiveDict(self.attributes,
                                              preserve=preserveCase)

        self.endTagName = self.nodeName = self.tagName = tagName
        self._filename = filename
        self._markpos = markpos
        self.namespace = namespace

    def addPrefixes(self, pfxs):
        if self.nsprefixes is None:
            self.nsprefixes = pfxs
        else:
            self.nsprefixes.update(pfxs)

    def endTag(self, endTagName):
        if not self.preserveCase:
            endTagName = endTagName.lower()
        self.endTagName = endTagName

    def isEqualToElement(self, n):
        if self.caseInsensitive:
            return ((self.attributes == n.attributes)
                    and (self.nodeName.lower() == n.nodeName.lower()))
        return (self.attributes == n.attributes) and (self.nodeName == n.nodeName)


    def isEqualToNode(self, other):
        """
        Compare this element to C{other}.  If the C{nodeName}, C{namespace},
        C{attributes}, and C{childNodes} are all the same, return C{True},
        otherwise return C{False}.
        """
        return (
            self.nodeName.lower() == other.nodeName.lower() and
            self.namespace == other.namespace and
            self.attributes == other.attributes and
            Node.isEqualToNode(self, other))


    def cloneNode(self, deep=0, parent=None):
        clone = Element(
            self.tagName, parentNode=parent, namespace=self.namespace,
            preserveCase=self.preserveCase, caseInsensitive=self.caseInsensitive)
        clone.attributes.update(self.attributes)
        if deep:
            clone.childNodes = [child.cloneNode(1, clone) for child in self.childNodes]
        else:
            clone.childNodes = []
        return clone

    def getElementsByTagName(self, name):
        if self.caseInsensitive:
            return getElementsByTagNameNoCase(self, name)
        return getElementsByTagName(self, name)

    def hasAttributes(self):
        return 1

    def getAttribute(self, name, default=None):
        return self.attributes.get(name, default)

    def getAttributeNS(self, ns, name, default=None):
        nsk = (ns, name)
        if self.attributes.has_key(nsk):
            return self.attributes[nsk]
        if ns == self.namespace:
            return self.attributes.get(name, default)
        return default

    def getAttributeNode(self, name):
        return _Attr(self.getAttribute(name), self)

    def setAttribute(self, name, attr):
        self.attributes[name] = attr

    def removeAttribute(self, name):
        if name in self.attributes:
            del self.attributes[name]

    def hasAttribute(self, name):
        return name in self.attributes


    def writexml(self, stream, indent='', addindent='', newl='', strip=0,
                 nsprefixes={}, namespace=''):
        """
        Serialize this L{Element} to the given stream.

        @param stream: A file-like object to which this L{Element} will be
            written.

        @param nsprefixes: A C{dict} mapping namespace URIs as C{str} to
            prefixes as C{str}.  This defines the prefixes which are already in
            scope in the document at the point at which this L{Element} exists.
            This is essentially an implementation detail for namespace support.
            Applications should not try to use it.

        @param namespace: The namespace URI as a C{str} which is the default at
            the point in the document at which this L{Element} exists.  This is
            essentially an implementation detail for namespace support.
            Applications should not try to use it.
        """
        # write beginning
        ALLOWSINGLETON = ('img', 'br', 'hr', 'base', 'meta', 'link', 'param',
                          'area', 'input', 'col', 'basefont', 'isindex',
                          'frame')
        BLOCKELEMENTS = ('html', 'head', 'body', 'noscript', 'ins', 'del',
                         'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'script',
                         'ul', 'ol', 'dl', 'pre', 'hr', 'blockquote',
                         'address', 'p', 'div', 'fieldset', 'table', 'tr',
                         'form', 'object', 'fieldset', 'applet', 'map')
        FORMATNICELY = ('tr', 'ul', 'ol', 'head')

        # this should never be necessary unless people start
        # changing .tagName on the fly(?)
        if not self.preserveCase:
            self.endTagName = self.tagName
        w = stream.write
        if self.nsprefixes:
            newprefixes = self.nsprefixes.copy()
            for ns in nsprefixes.keys():
                if ns in newprefixes:
                    del newprefixes[ns]
        else:
             newprefixes = {}

        begin = ['<']
        if self.tagName in BLOCKELEMENTS:
            begin = [newl, indent] + begin
        bext = begin.extend
        writeattr = lambda _atr, _val: bext((' ', _atr, '="', escape(_val), '"'))

        # Make a local for tracking what end tag will be used.  If namespace
        # prefixes are involved, this will be changed to account for that
        # before it's actually used.
        endTagName = self.endTagName

        if namespace != self.namespace and self.namespace is not None:
            # If the current default namespace is not the namespace of this tag
            # (and this tag has a namespace at all) then we'll write out
            # something related to namespaces.
            if self.namespace in nsprefixes:
                # This tag's namespace already has a prefix bound to it.  Use
                # that prefix.
                prefix = nsprefixes[self.namespace]
                bext(prefix + ':' + self.tagName)
                # Also make sure we use it for the end tag.
                endTagName = prefix + ':' + self.endTagName
            else:
                # This tag's namespace has no prefix bound to it.  Change the
                # default namespace to this tag's namespace so we don't need
                # prefixes.  Alternatively, we could add a new prefix binding.
                # I'm not sure why the code was written one way rather than the
                # other. -exarkun
                bext(self.tagName)
                writeattr("xmlns", self.namespace)
                # The default namespace just changed.  Make sure any children
                # know about this.
                namespace = self.namespace
        else:
            # This tag has no namespace or its namespace is already the default
            # namespace.  Nothing extra to do here.
            bext(self.tagName)

        j = ''.join
        for attr, val in self.attributes.iteritems():
            if isinstance(attr, tuple):
                ns, key = attr
                if nsprefixes.has_key(ns):
                    prefix = nsprefixes[ns]
                else:
                    prefix = genprefix()
                    newprefixes[ns] = prefix
                assert val is not None
                writeattr(prefix+':'+key,val)
            else:
                assert val is not None
                writeattr(attr, val)
        if newprefixes:
            for ns, prefix in newprefixes.iteritems():
                if prefix:
                    writeattr('xmlns:'+prefix, ns)
            newprefixes.update(nsprefixes)
            downprefixes = newprefixes
        else:
            downprefixes = nsprefixes
        w(j(begin))
        if self.childNodes:
            w(">")
            newindent = indent + addindent
            for child in self.childNodes:
                if self.tagName in BLOCKELEMENTS and \
                   self.tagName in FORMATNICELY:
                    w(j((newl, newindent)))
                child.writexml(stream, newindent, addindent, newl, strip,
                               downprefixes, namespace)
            if self.tagName in BLOCKELEMENTS:
                w(j((newl, indent)))
            w(j(('</', endTagName, '>')))
        elif self.tagName.lower() not in ALLOWSINGLETON:
            w(j(('></', endTagName, '>')))
        else:
            w(" />")


    def __repr__(self):
        rep = "Element(%s" % repr(self.nodeName)
        if self.attributes:
            rep += ", attributes=%r" % (self.attributes,)
        if self._filename:
            rep += ", filename=%r" % (self._filename,)
        if self._markpos:
            rep += ", markpos=%r" % (self._markpos,)
        return rep + ')'

    def __str__(self):
        rep = "<" + self.nodeName
        if self._filename or self._markpos:
            rep += " ("
        if self._filename:
            rep += repr(self._filename)
        if self._markpos:
            rep += " line %s column %s" % self._markpos
        if self._filename or self._markpos:
            rep += ")"
        for item in self.attributes.items():
            rep += " %s=%r" % item
        if self.hasChildNodes():
            rep += " >...</%s>" % self.nodeName
        else:
            rep += " />"
        return rep
Beispiel #36
0
    def __send_http_response(self, inh, request, response_msg):
        """
        When we've know what message to send back to the HTTP client
        which has connected to the HTTP server, we issue this message back.

        @param inh: an inhabinant who will receive the response
        @type inh: AbstractInhabitant

        @param request: web server request.
        @type request: Request

        @param response_msg: response message to send.
        @type response_msg: AbstractMessage
        """
        if not self.connection_alive:
            logger.debug('Connection died inside %r while trying '
                             'to reply with %r',
                         self, response_msg)
            # That's very very bad! We should put the message back to queue.
            self.tr_manager.post_message(response_msg)
        else:
            logger.debug('Sending response %r to %r',
                         response_msg, request.requestHeaders)

            response_msg.in_transfer = True

            # Add the default server-specific headers,
            # then the message-specific headers.
            _headers = InsensitiveDict(dict(request.responseHeaders
                                                   .getAllRawHeaders()))
            _pragma = ','.join(ifilter(None, [response_msg.get_pragma(),
                                              self.extra_pragma()]))
            HTTPTransport.update_headers(_headers, {'Pragma': [_pragma]})
            HTTPTransport.update_headers(_headers, response_msg.get_headers())
            for k, v_list in _headers.iteritems():
                request.responseHeaders.setRawHeaders(k, v_list)

            logger.debug('New headers for %r are: %r',
                         response_msg, request.responseHeaders)


            @contract_epydoc
            def produce_body_in_main(body, msg):
                """
                @type body: col.Iterable
                @type msg: AbstractMessage
                """
                assert in_main_thread()

                try:
                    producer = LazyPullProducer(request, body)
                    producer.completed.addBoth(self._ready_to_finish.callback)
                except Exception:
                    logger.exception('Error during writing back the request:')
                    # We haven't succeeded to send the message to the client.
                    # Put it back to the queue.
                    callInThread(self.tr_manager.post_message, msg)


            assert not in_main_thread()  # get_body() may take long
            _body = response_msg.get_body()
            logger.debug('Writing body: %r', response_msg)

            callFromThread(produce_body_in_main, _body, response_msg)
Beispiel #37
0
    def __send_http_response(self, inh, request, response_msg):
        """
        When we've know what message to send back to the HTTP client
        which has connected to the HTTP server, we issue this message back.

        @param inh: an inhabinant who will receive the response
        @type inh: AbstractInhabitant

        @param request: web server request.
        @type request: Request

        @param response_msg: response message to send.
        @type response_msg: AbstractMessage
        """
        if not self.connection_alive:
            logger.debug(
                'Connection died inside %r while trying '
                'to reply with %r', self, response_msg)
            # That's very very bad! We should put the message back to queue.
            self.tr_manager.post_message(response_msg)
        else:
            logger.debug('Sending response %r to %r', response_msg,
                         request.requestHeaders)

            response_msg.in_transfer = True

            # Add the default server-specific headers,
            # then the message-specific headers.
            _headers = InsensitiveDict(
                dict(request.responseHeaders.getAllRawHeaders()))
            _pragma = ','.join(
                ifilter(None, [response_msg.get_pragma(),
                               self.extra_pragma()]))
            HTTPTransport.update_headers(_headers, {'Pragma': [_pragma]})
            HTTPTransport.update_headers(_headers, response_msg.get_headers())
            for k, v_list in _headers.iteritems():
                request.responseHeaders.setRawHeaders(k, v_list)

            logger.debug('New headers for %r are: %r', response_msg,
                         request.responseHeaders)

            @contract_epydoc
            def produce_body_in_main(body, msg):
                """
                @type body: col.Iterable
                @type msg: AbstractMessage
                """
                assert in_main_thread()

                try:
                    producer = LazyPullProducer(request, body)
                    producer.completed.addBoth(self._ready_to_finish.callback)
                except Exception:
                    logger.exception('Error during writing back the request:')
                    # We haven't succeeded to send the message to the client.
                    # Put it back to the queue.
                    callInThread(self.tr_manager.post_message, msg)

            assert not in_main_thread()  # get_body() may take long
            _body = response_msg.get_body()
            logger.debug('Writing body: %r', response_msg)

            callFromThread(produce_body_in_main, _body, response_msg)
Beispiel #38
0
class IRCBot(irc.IRCClient):
    sasl_buffer = ""
    sasl_result = None
    sasl_login = None

    def __init__(self, factory, plugin):
        self.factory = factory
        self.nickname = plugin.nickname.encode('ascii')
        self.realname = plugin.realname.encode('ascii')
        self.username = plugin.ident.encode('ascii')
        self.ns_username = plugin.username
        self.ns_password = plugin.password
        self.password = plugin.server_password.encode('ascii')
        self.channel = plugin.channel.encode('ascii')
        self.key = plugin.key.encode('ascii')
        self.console = plugin.console
        self.irc_message = plugin.irc_message
        self.irc_action = plugin.irc_action
        self.irc_chat_status = plugin.irc_chat_status
        self.mangle_username = plugin.mangle_username

        self.users = InsensitiveDict()
        self.cap_requests = set()

    def register(self, nickname, hostname="foo", servername="bar"):
        self.sendLine("CAP LS")
        return irc.IRCClient.register(self, nickname, hostname, servername)

    def sendLine(self, line):
        irc.IRCClient.sendLine(self, line.encode('ascii', 'replace'))

    def _parse_cap(self, cap):
        mod = ''
        while cap[0] in "-~=":
            mod, cap = mod + cap[0], cap[1:]
        if '/' in cap:
            vendor, cap = cap.split('/', 1)
        else:
            vendor = None
        return (cap, mod, vendor)

    def request_cap(self, *caps):
        self.cap_requests |= set(caps)
        self.sendLine("CAP REQ :{}".format(' '.join(caps)))

    @defer.inlineCallbacks
    def end_cap(self):
        if self.sasl_result:
            yield self.sasl_result
        self.sendLine("CAP END")

    def irc_CAP(self, prefix, params):
        self.supports_cap = True
        identifier, subcommand, args = params
        args = args.split(' ')
        if subcommand == "LS":
            self.sasl_start(args)
            if not self.cap_requests:
                self.sendLine("CAP END")
        elif subcommand == "ACK":
            ack = []
            for cap in args:
                if not cap:
                    continue
                cap, mod, vendor = self._parse_cap(cap)
                if '-' in mod:
                    if cap in self.capabilities:
                        del self.capabilities[cap]
                    continue
                self.cap_requests.remove(cap)
                if cap == 'sasl':
                    self.sasl_next()
            if ack:
                self.sendLine("CAP ACK :{}".format(' '.join(ack)))
            if not self.cap_requests:
                self.end_cap()
        elif subcommand == "NAK":
            # this implementation is probably not compliant but it will have to do for now
            for cap in args:
                self.cap_requests.remove(cap)
            if not self.cap_requests:
                self.end_cap()

    def signedOn(self):
        if ISSLTransport.providedBy(self.transport):
            cert = self.transport.getPeerCertificate()
            fp = cert.digest("sha1")
            verified = "verified" if self.factory.parent.server_fingerprint else "unverified"
            self.console(
                "irc: connected securely. server fingerprint: {} ({})".format(
                    fp, verified))
        else:
            self.console("irc: connected")

        if self.ns_username and self.ns_password and not self.sasl_login:
            self.msg(
                'NickServ', 'IDENTIFY {} {}'.format(self.ns_username,
                                                    self.ns_password))

        self.join(self.channel, self.key)

    def irc_JOIN(self, prefix, params):
        nick = prefix.split('!')[0]
        channel = params[-1]
        if nick == self.nickname:
            self.joined(channel)
        else:
            self.userJoined(prefix, channel)

    def joined(self, channel):
        self.console('irc: joined channel')
        self.factory.client = self

        def who(a):
            self.sendLine("WHO " + channel)

        self.factory.parent.repeating_task(who, 30, now=True)

    def isupport(self, args):
        self.compute_prefix_names()

    def compute_prefix_names(self):
        KNOWN_NAMES = {"o": "op", "h": "halfop", "v": "voice"}
        prefixdata = self.supported.getFeature("PREFIX", {
            "o": ("@", 0),
            "v": ("+", 1)
        }).items()
        op_priority = ([
            priority for mode, (prefix, priority) in prefixdata if mode == "o"
        ] + [None])[0]
        self.prefixes, self.statuses, self.priority = {}, {}, {}

        for mode, (prefix, priority) in prefixdata:
            name = "?"
            if mode in KNOWN_NAMES:
                name = KNOWN_NAMES[mode]
            elif priority == 0:
                if op_priority == 2:
                    name = "owner"
                else:
                    name = "admin"
            else:
                name = "+" + mode
            self.prefixes[mode] = prefix
            self.statuses[prefix] = name
            self.priority[name] = priority
            self.priority[mode] = priority
            self.priority[prefix] = priority

    def parse_prefixes(self, user, nick, prefixes=''):
        status = []
        prefixdata = self.supported.getFeature("PREFIX", {
            "o": ("@", 0),
            "v": ("+", 1)
        }).items()
        for mode, (prefix, priority) in prefixdata:
            if prefix in prefixes + nick:
                nick = nick.replace(prefix, '')
                status.append((prefix, priority))
        if nick == self.nickname:
            return
        user.status = ''.join(t[0] for t in sorted(status, key=lambda t: t[1]))

    def irc_RPL_WHOREPLY(self, prefix, params):
        _, channel, username, host, server, nick, status, hg = params
        if nick == self.nickname:
            return
        hops, gecos = hg.split(' ', 1)
        user = IRCUser(self, nick)
        user.username = username
        user.hostname = host
        user.oper = '*' in status
        user.away = status[0] == 'G'
        self.users[nick] = user
        self.parse_prefixes(user, nick, status[1:].replace('*', ''))

    def modeChanged(self, user, channel, _set, modes, args):
        args = list(args)
        if channel.lower() != self.channel.lower():
            return
        for m, arg in zip(modes, args):
            if m in self.prefixes and arg != self.nickname:
                u = self.users.get(arg, None)
                if u:
                    u.status = u.status.replace(self.prefixes[m], '')
                    if _set:
                        u.status = ''.join(
                            sorted(list(u.status + self.prefixes[m]),
                                   key=lambda k: self.priority[k]))

    def has_status(self, nick, status):
        if status != 0 and not status:
            return True
        if status not in self.priority:
            return False
        priority = self.priority[status]
        u = self.users.get(nick, None)
        return u and (u.priority is not None) and u.priority <= priority

    def userJoined(self, user, channel):
        nick = user.split('!')[0]
        user = IRCUser(self, nick)
        self.users[nick] = user

    def userRenamed(self, oldname, newname):
        if oldname not in self.users:
            return
        u = self.users[oldname]
        u.nick = newname
        self.users[newname] = u
        del self.users[oldname]

    def userLeft(self, user, channel):
        if user not in self.users:
            return
        del self.users[user]

    def userKicked(self, kickee, channel, kicker, message):
        if kickee not in self.users:
            return
        del self.users[kickee]

    def userQuit(self, user, quitMessage):
        if user not in self.users:
            return
        del self.users[user]

    def privmsg(self, user, channel, msg):
        if channel != self.channel:
            return
        if '!' not in user:
            return
        nick = user.split('!')[0]
        p = self.factory.parent

        if not self.has_status(nick, self.irc_chat_status):
            return

        if p.irc_players_enabled and msg.lower(
        ) == p.irc_command_prefix + "players":
            self.say(
                self.channel,
                p.irc_players_format.format(
                    players=', '.join(map(self.mangle_username, p.players))))

        elif p.irc_command_prefix and msg.startswith(
                p.irc_command_prefix
        ) and p.irc_command_status and self.has_status(nick,
                                                       p.irc_command_status):
            argv = msg[len(p.irc_command_prefix):].split(' ')
            command = argv[0]
            if command.startswith('~'):
                if p.irc_command_mark2 and (
                        command.lower()
                        in p.irc_command_allow.lower().split(',')
                        or p.irc_command_allow == '*'):
                    p.dispatch(Hook(line=' '.join(argv)))
            else:
                if command.lower() in p.irc_command_allow.lower().split(
                        ',') or p.irc_command_allow == '*':
                    p.send(' '.join(argv))

        else:
            self.irc_message(nick, msg)

    def action(self, user, channel, msg):
        self.console("%s %s %s" % (user, channel, msg))
        if channel != self.channel:
            return
        if '!' not in user:
            return
        nick = user.split('!')[0]

        if self.has_status(nick, self.irc_chat_status):
            self.irc_action(nick, msg)

    def irc_AUTHENTICATE(self, prefix, params):
        self.sasl_continue(params[0])

    def sasl_send(self, data):
        while data and len(data) >= 400:
            en, data = data[:400].encode('base64').replace('\n',
                                                           ''), data[400:]
            self.sendLine("AUTHENTICATE " + en)
        if data:
            self.sendLine("AUTHENTICATE " +
                          data.encode('base64').replace('\n', ''))
        else:
            self.sendLine("AUTHENTICATE +")

    def sasl_start(self, cap_list):
        if 'sasl' not in cap_list:
            print(cap_list)
            return
        self.request_cap('sasl')
        self.sasl_result = defer.Deferred()
        self.sasl_mechanisms = list(SASL_MECHANISMS)

    def sasl_next(self):
        mech = None
        while not mech or not mech.is_valid():
            if not self.sasl_mechanisms:
                return False
            self.sasl_auth = mech = self.sasl_mechanisms.pop(0)(
                self.ns_username, self.ns_password)
        self.sendLine("AUTHENTICATE " + self.sasl_auth.name)
        return True

    def sasl_continue(self, data):
        if data == '+':
            data = ''
        else:
            data = data.decode('base64')
        if len(data) == 400:
            self.sasl_buffer += data
        else:
            response = self.sasl_auth.respond(self.sasl_buffer + data)
            if response is False:  # abort
                self.sendLine("AUTHENTICATE *")
            else:
                self.sasl_send(response)
            self.sasl_buffer = ""

    def sasl_finish(self):
        if self.sasl_result:
            self.sasl_result.callback(True)
            self.sasl_result = None

    def sasl_failed(self, whine=True):
        if self.sasl_login is False:
            return
        if self.sasl_next():
            return
        self.sasl_login = False
        self.sendLine("AUTHENTICATE *")
        self.sasl_finish()
        if whine:
            self.console("irc: failed to log in.")

    def irc_904(self, prefix, params):
        print(params)
        self.sasl_failed()

    def irc_905(self, prefix, params):
        print(params)
        self.sasl_failed()

    def irc_906(self, prefix, params):
        self.sasl_failed(False)

    def irc_907(self, prefix, params):
        self.sasl_failed(False)

    def irc_900(self, prefix, params):
        self.sasl_login = params[2]
        self.console("irc: logged in as '{}' (using {})".format(
            self.sasl_login, self.sasl_auth.name))

    def irc_903(self, prefix, params):
        self.sasl_finish()

    def alterCollidedNick(self, nickname):
        return nickname + '_'

    def irc_relay(self, message):
        self.say(self.channel, message.encode('utf8'))
Beispiel #39
0
class IRCBot(irc.IRCClient):
    sasl_buffer = ""
    sasl_result = None
    sasl_login = None

    cancel_hilight_re = re.compile(ur"(?:(?<=\u00a7[0-9a-flmnor])|(?<!\u00a7)\b).+?\b")

    def __init__(self, factory, parent):
        self.factory     = factory
        self.nickname    = parent.nickname.encode('ascii')
        self.realname    = parent.realname.encode('ascii')
        self.username    = parent.ident.encode('ascii')
        self.ns_username = parent.username
        self.ns_password = parent.password
        self.password    = parent.server_password.encode('ascii')
        self.join_channels = parent.channel_map.keys()

        self.users        = InsensitiveDict()
        self.channels     = InsensitiveDict()
        self.cap_requests = set()

        self.parent = parent

    def register(self, nickname, hostname="foo", servername="bar"):
        self.sendLine("CAP LS")
        return irc.IRCClient.register(self, nickname, hostname, servername)

    def sendLine(self, line):
        if isinstance(line, unicode):
            line = line.encode('utf8', 'replace')
        irc.IRCClient.sendLine(self, line)

    def _parse_cap(self, cap):
        mod = ''
        while cap[0] in "-~=":
            mod, cap = mod + cap[0], cap[1:]
        if '/' in cap:
            vendor, cap = cap.split('/', 1)
        else:
            vendor = None
        return (cap, mod, vendor)

    def request_cap(self, *caps):
        self.cap_requests |= set(caps)
        self.sendLine("CAP REQ :{0}".format(' '.join(caps)))

    @defer.inlineCallbacks
    def end_cap(self):
        if self.sasl_result:
            yield self.sasl_result
        self.sendLine("CAP END")

    def irc_CAP(self, prefix, params):
        self.supports_cap = True
        identifier, subcommand, args = params
        args = args.split(' ')
        if subcommand == "LS":
            self.sasl_start(args)
            if not self.cap_requests:
                self.sendLine("CAP END")
        elif subcommand == "ACK":
            ack = []
            for cap in args:
                if not cap:
                    continue
                cap, mod, vendor = self._parse_cap(cap)
                if '-' in mod:
                    if cap in self.capabilities:
                        del self.capabilities[cap]
                    continue
                self.cap_requests.remove(cap)
                if cap == 'sasl':
                    self.sasl_next()
            if ack:
                self.sendLine("CAP ACK :{0}".format(' '.join(ack)))
            if not self.cap_requests:
                self.end_cap()
        elif subcommand == "NAK":
            # this implementation is probably not compliant but it will have to do for now
            for cap in args:
                self.cap_requests.remove(cap)
            if not self.cap_requests:
                self.end_cap()

    def signedOn(self):
        if ISSLTransport.providedBy(self.transport):
            cert = self.transport.getPeerCertificate()
            fp = cert.digest("sha1")
            verified = "verified" if self.factory.parent.server_fingerprint else "unverified"
            print("irc: connected securely. server fingerprint: {0} ({1})".format(fp, verified))
        else:
            print("irc: connected")
        
        if self.ns_username and self.ns_password and not self.sasl_login:
            self.msg('NickServ', 'IDENTIFY {0} {1}'.format(self.ns_username, self.ns_password))
        
        for channel in self.join_channels:
            self.join(channel)

    def irc_JOIN(self, prefix, params):
        nick = prefix.split('!')[0]
        channel = params[-1]
        if nick == self.nickname:
            self.joined(channel)
        else:
            self.userJoined(prefix, channel)

    def joined(self, channel):
        print('irc: joined channel')
        self.factory.client = self
        def who():
            self.sendLine("WHO " + channel)
        task.LoopingCall(who).start(30)
    
    def isupport(self, args):
        self.compute_prefix_names()
        
    def compute_prefix_names(self):
        KNOWN_NAMES = {"o": "op", "h": "halfop", "v": "voice"}
        prefixdata = self.supported.getFeature("PREFIX", {"o": ("@", 0), "v": ("+", 1)}).items()
        op_priority = ([priority for mode, (prefix, priority) in prefixdata if mode == "o"] + [None])[0]
        self.prefixes, self.statuses, self.priority = {}, {}, {}

        for mode, (prefix, priority) in prefixdata:
            name = "?"
            if mode in KNOWN_NAMES:
                name = KNOWN_NAMES[mode]
            elif priority == 0:
                if op_priority == 2:
                    name = "owner"
                else:
                    name = "admin"
            else:
                name = "+" + mode
            self.prefixes[mode] = prefix
            self.statuses[prefix] = name
            self.priority[name] = priority
            self.priority[mode] = priority
            self.priority[prefix] = priority

    def parse_prefixes(self, user, nick, prefixes=''):
        status = []
        prefixdata = self.supported.getFeature("PREFIX", {"o": ("@", 0), "v": ("+", 1)}).items()
        for mode, (prefix, priority) in prefixdata:
            if prefix in prefixes + nick:
                nick = nick.replace(prefix, '')
                status.append((prefix, priority))
        if nick == self.nickname:
            return
        user.status = ''.join(t[0] for t in sorted(status, key=lambda t: t[1]))
    
    def irc_RPL_WHOREPLY(self, prefix, params):
        _, channel, username, host, server, nick, status, hg = params
        if nick == self.nickname:
            return
        hops, gecos = hg.split(' ', 1)
        user = self.get_user(nick) or IRCUser(self, nick)
        user.username = username
        user.hostname = host
        user.oper = '*' in status
        user.away = status[0] == 'G'
        self.users[nick] = user
        self.get_channel(channel)[nick] = IRCUserInChannel(user, channel)
        self.parse_prefixes(user, nick, status[1:].replace('*', ''))
    
    def modeChanged(self, user, channel, _set, modes, args):
        args = list(args)
        if channel not in self.parent.channel_map:
            return
        for m, arg in zip(modes, args):
            if m in self.prefixes and arg != self.nickname:
                u = self.get_user(arg).on(channel)
                if u:
                    u.status = u.status.replace(self.prefixes[m], '')
                    if _set:
                        u.status = ''.join(sorted(list(u.status + self.prefixes[m]),
                                                  key=lambda k: self.priority[k]))

    def has_status(self, nick, status):
        if status != 0 and not status:
            return True
        if status not in self.priority:
            return False
        priority = self.priority[status]
        u = self.users.get(nick, None)
        return u and (u.priority is not None) and u.priority <= priority

    def get_channel(self, channel):
        return self.channels.setdefault(channel, InsensitiveDict())

    def get_user(self, nick):
        return self.users.get(nick, False)
    
    def userJoined(self, user, channel):
        nick = user.split('!')[0]
        user = IRCUser(self, nick)
        self.users[nick] = user
        self.get_channel(channel)[nick] = IRCUserInChannel(user, channel)
    
    def userRenamed(self, oldname, newname):
        if oldname not in self.users:
            return
        u = self.users[oldname]
        u.nick = newname
        self.users[newname] = u
        del self.users[oldname]
        for k, v in self.channels.items():
            if oldname in v:
                v[newname] = v[oldname]
                del v[oldname]
    
    def userLeft(self, user, channel):
        if user not in self.users:
            return
        del self.users[user]
        for k, v in self.channels.items():
            if user in v:
                del v[user]
    
    def userKicked(self, kickee, channel, kicker, message):
        if kickee not in self.users:
            return
        del self.users[kickee]
        for k, v in self.channels.items():
            if user in v:
                del v[user]
    
    def userQuit(self, user, quitMessage):
        if user not in self.users:
            return
        del self.users[user]
        for k, v in self.channels.items():
            if user in v:
                del v[user]

    def privmsg(self, user, channel, msg):
        pass

    def action(self, user, channel, msg):
        pass

    def irc_AUTHENTICATE(self, prefix, params):
        self.sasl_continue(params[0])

    def sasl_send(self, data):
        while data and len(data) >= 400:
            en, data = data[:400].encode('base64').replace('\n', ''), data[400:]
            self.sendLine("AUTHENTICATE " + en)
        if data:
            self.sendLine("AUTHENTICATE " + data.encode('base64').replace('\n', ''))
        else:
            self.sendLine("AUTHENTICATE +")

    def sasl_start(self, cap_list):
        if 'sasl' not in cap_list:
            return
        self.request_cap('sasl')
        self.sasl_result = defer.Deferred()
        self.sasl_mechanisms = list(SASL_MECHANISMS)

    def sasl_next(self):
        mech = None
        while not mech or not mech.is_valid():
            if not self.sasl_mechanisms:
                return False
            self.sasl_auth = mech = self.sasl_mechanisms.pop(0)(self.ns_username, self.ns_password)
        self.sendLine("AUTHENTICATE " + self.sasl_auth.name)
        return True

    def sasl_continue(self, data):
        if data == '+':
            data = ''
        else:
            data = data.decode('base64')
        if len(data) == 400:
            self.sasl_buffer += data
        else:
            response = self.sasl_auth.respond(self.sasl_buffer + data)
            if response is False:  # abort
                self.sendLine("AUTHENTICATE *")
            else:
                self.sasl_send(response)
            self.sasl_buffer = ""

    def sasl_finish(self):
        if self.sasl_result:
            self.sasl_result.callback(True)
            self.sasl_result = None

    def sasl_failed(self, whine=True):
        if self.sasl_login is False:
            return
        if self.sasl_next():
            return
        self.sasl_login = False
        self.sendLine("AUTHENTICATE *")
        self.sasl_finish()
        if whine:
            print("irc: failed to log in.")

    def irc_904(self, prefix, params):
        self.sasl_failed()

    def irc_905(self, prefix, params):
        self.sasl_failed()

    def irc_906(self, prefix, params):
        self.sasl_failed(False)

    def irc_907(self, prefix, params):
        self.sasl_failed(False)

    def irc_900(self, prefix, params):
        self.sasl_login = params[2]
        print("irc: logged in as '{0}' (using {1})".format(self.sasl_login, self.sasl_auth.name))

    def irc_903(self, prefix, params):
        self.sasl_finish()

    def alterCollidedNick(self, nickname):
        return nickname + '_'

    def cancel_hilights(self, channel, text):
        def hl(match):
            s = match.group(0)
            if len(s) >= 2 and s in self.get_channel(channel):
                return s[:-1] + '*' + s[-1]
            else:
                return s
        return self.cancel_hilight_re.sub(hl, text)

    def translate_colors(self, text):
        tr = {
            "0": "\x0301",
            "1": "\x0302",
            "2": "\x0303",
            "3": "\x0310",
            "4": "\x0304",
            "5": "\x0306",
            "6": "\x0308",
            "7": "\x0315",
            "8": "\x0314",
            "9": "\x0312",
            "a": "\x0309",
            "b": "\x0311",
            "c": "\x0304",
            "d": "\x0313",
            "e": "\x0308",
            "f": "\x0F",
        }
        return re.sub(ur"\u00a7([0-9a-f])", lambda m: tr.get(m.group(1), ""), text)

    def irc_relay(self, channel, message):
        message = message.decode('utf8')
        self.say(channel, self.translate_colors(self.cancel_hilights(channel, message)))
Beispiel #40
0
class Element(Node):
    nsprefixes = None
    create_attr = lambda k, v: (' ', k, '="', escape(v), '"')

    SINGLETONS = ('img', 'br', 'hr', 'base', 'meta', 'link', 'param', 'area',
                  'input', 'col', 'basefont', 'isindex', 'frame')

    BLOCKELEMENTS = ('html', 'head', 'body', 'noscript', 'ins', 'del', 'h1',
                     'h2', 'h3', 'h4', 'h5', 'h6', 'script', 'ul', 'ol', 'dl',
                     'pre', 'hr', 'blockquote', 'address', 'p', 'div',
                     'fieldset', 'table', 'tr', 'form', 'object', 'fieldset',
                     'applet', 'map')

    NICEFORMATS = ('tr', 'ul', 'ol', 'head')

    def __init__(self,
                 tagName,
                 attributes=None,
                 parentNode=None,
                 filename=None,
                 markpos=None,
                 case_insensitive=1,
                 namespace=None):
        Node.__init__(self, parentNode)
        preserve_case = not case_insensitive
        tagName = tagName if preserve_case else tagName.lower()
        unescaped = unescape_dict(attributes or {})

        if case_insensitive:
            self.attributes = InsensitiveDict(unescaped,
                                              preserve=preserve_case)
        else:
            self.attributes = unescaped

        self.preserve_case = not case_insensitive
        self.case_insensitive = case_insensitive
        self.endTagName = self.nodeName = self.tagName = tagName
        self._filename = filename
        self._markpos = markpos
        self.namespace = namespace
        self.tag_is_blockelement = tagName in self.BLOCKELEMENTS
        self.tag_is_nice_format = tagName in self.NICEFORMATS
        self.tag_is_singleton = tagName.lower() in self.SINGLETONS

    def addPrefixes(self, pfxs):
        if self.nsprefixes is None:
            self.nsprefixes = pfxs
        else:
            self.nsprefixes.update(pfxs)

    def endTag(self, endTagName):
        if self.case_insensitive:
            endTagName = endTagName.lower()

        self.endTagName = endTagName

    def isEqualToElement(self, n):
        same_attrs = self.attributes == n.attributes

        if self.case_insensitive:
            eq = same_attrs and (self.nodeName.lower() == n.nodeName.lower())
        else:
            eq = same_attrs and (self.nodeName == n.nodeName)

        return eq

    def isEqualToNode(self, other):
        """
        Compare this element to C{other}.  If the C{nodeName}, C{namespace},
        C{attributes}, and C{childNodes} are all the same, return C{True},
        otherwise return C{False}.
        """
        return (self.nodeName.lower() == other.nodeName.lower()
                and self.namespace == other.namespace
                and self.attributes == other.attributes
                and Node.isEqualToNode(self, other))

    def cloneNode(self, deep=0, parent=None):
        clone = Element(self.tagName,
                        parentNode=parent,
                        namespace=self.namespace,
                        case_insensitive=self.case_insensitive)

        clone.attributes.update(self.attributes)

        if deep:
            clone.childNodes = [
                child.cloneNode(1, clone) for child in self.childNodes
            ]
        else:
            clone.childNodes = []

        return clone

    def getElementsByTagName(self, name):
        icase = self.case_insensitive
        return getElementsByTagName(self.childNodes, name, icase)

    def hasAttributes(self):
        return 1

    def getAttribute(self, name, default=None):
        return self.attributes.get(name, default)

    def getAttributeNS(self, ns, name, default=None):
        nsk = (ns, name)

        if nsk in self.attributes:
            return self.attributes[nsk]

        if ns == self.namespace:
            return self.attributes.get(name, default)

        return default

    def getAttributeNode(self, name):
        return _Attr(self.getAttribute(name), self)

    def setAttribute(self, name, attr):
        self.attributes[name] = attr

    def removeAttribute(self, name):
        if name in self.attributes:
            del self.attributes[name]

    def hasAttribute(self, name):
        return name in self.attributes

    def gen_prefixes(self, nsprefixes):
        for k, v in self.nsprefixes.items():
            if k not in nsprefixes:
                yield (k, v)

    def _writexml(self, namespace, nsprefixes, newl, indent):
        newprefixes = dict(self.gen_prefixes(nsprefixes))
        begin = [newl, indent, '<'] if self.tag_is_blockelement else ['<']
        is_same_namespace = self.namespace and namespace == self.namespace

        # Make a local for tracking what end tag will be used. If namespace
        # prefixes are involved, this will be changed to account for that
        # before it's actually used.
        endTagName = self.endTagName

        if not is_same_namespace and self.namespace in nsprefixes:
            # This tag's namespace already has a prefix bound to it. Use
            # that prefix.
            prefix = nsprefixes[self.namespace]
            begin.extend(prefix + ':' + self.tagName)

            # Also make sure we use it for the end tag.
            endTagName = prefix + ':' + self.endTagName
        elif not is_same_namespace:
            # This tag's namespace has no prefix bound to it. Change the
            # default namespace to this tag's namespace so we don't need
            # prefixes.  Alternatively, we could add a new prefix binding.
            # I'm not sure why the code was written one way rather than the
            # other. -exarkun
            begin.extend(self.tagName)
            begin.extend(self.create_attr("xmlns", self.namespace))

            # The default namespace just changed.  Make sure any children
            # know about this.
            namespace = self.namespace
        else:
            # This tag has no namespace or its namespace is already the default
            # namespace.  Nothing extra to do here.
            begin.extend(self.tagName)

        prefixes = ('p%s' % str(i) for i in it.count())

        for attr, val in sorted(self.attributes.items()):
            if val and isinstance(attr, tuple):
                ns, key = attr

                if ns in nsprefixes:
                    prefix = nsprefixes[ns]
                else:
                    newprefixes[ns] = prefix = next(prefixes)

                begin.extend(self.create_attr(prefix + ':' + key, val))
            elif val:
                begin.extend(self.create_attr(attr, val))

        return begin, namespace, endTagName, newprefixes

    def _write_child(self, stream, newl, newindent, **kwargs):
        for child in self.childNodes:
            if self.tag_is_blockelement and self.tag_is_nice_format:
                stream.write(''.join((newl, newindent)))

            child.writexml(stream, newl=newl, newindent=newindent, **kwargs)

    def writexml(self, stream, *args, **kwargs):
        """
        Serialize this L{Element} to the given stream.

        @param stream: A file-like object to which this L{Element} will be
            written.

        @param nsprefixes: A C{dict} mapping namespace URIs as C{str} to
            prefixes as C{str}.  This defines the prefixes which are already in
            scope in the document at the point at which this L{Element} exists.
            This is essentially an implementation detail for namespace support.
            Applications should not try to use it.

        @param namespace: The namespace URI as a C{str} which is the default at
            the point in the document at which this L{Element} exists.  This is
            essentially an implementation detail for namespace support.
            Applications should not try to use it.
        """
        indent = kwargs.get('indent', '')
        addindent = kwargs.get('addindent', '')
        newl = kwargs.get('newl', '')
        strip = kwargs.get('strip', 0)
        nsprefixes = kwargs.get('nsprefixes', {})
        namespace = kwargs.get('namespace', '')

        # this should never be necessary unless people start
        # changing .tagName on the fly(?)
        if self.case_insensitive:
            self.endTagName = self.tagName

        _args = (namespace, nsprefixes, newl, indent)
        begin, namespace, endTagName, newprefixes = self._writexml(*_args)

        for ns, prefix in newprefixes.items():
            if prefix:
                begin.extend(self.create_attr('xmlns:' + prefix, ns))

        newprefixes.update(nsprefixes)
        downprefixes = newprefixes
        stream.write(''.join(begin))

        if self.childNodes:
            stream.write(">")
            newindent = indent + addindent

            kwargs = {
                'newindent': newindent,
                'addindent': addindent,
                'newl': newl,
                'strip': strip,
                'downprefixes': downprefixes,
                'namespace': namespace
            }

            self._write_child(stream, newl, newindent, **kwargs)

            if self.tag_is_blockelement:
                stream.write(''.join((newl, indent)))

            stream.write(''.join(('</', endTagName, '>')))
        elif not self.tag_is_singleton:
            stream.write(''.join(('></', endTagName, '>')))
        else:
            stream.write(" />")

    def __repr__(self):
        rep = "Element(%s" % repr(self.nodeName)

        if self.attributes:
            rep += ", attributes=%r" % (self.attributes, )

        if self._filename:
            rep += ", filename=%r" % (self._filename, )

        if self._markpos:
            rep += ", markpos=%r" % (self._markpos, )

        return rep + ')'

    def __str__(self):
        rep = "<" + self.nodeName

        if self._filename or self._markpos:
            rep += " ("

        if self._filename:
            rep += repr(self._filename)

        if self._markpos:
            rep += " line %s column %s" % self._markpos

        if self._filename or self._markpos:
            rep += ")"

        for item in self.attributes.items():
            rep += " %s=%r" % item

        if self.hasChildNodes():
            rep += " >...</%s>" % self.nodeName
        else:
            rep += " />"

        return rep
Beispiel #41
0
class IRCBot(irc.IRCClient):
    def __init__(self, factory, plugin):
        self.factory     = factory
        self.nickname    = plugin.nickname.encode('ascii')
        self.realname    = plugin.realname.encode('ascii')
        self.username    = plugin.username.encode('ascii')
        self.ns_password = plugin.password
        self.password    = plugin.server_password.encode('ascii')
        self.channel     = plugin.channel.encode('ascii')
        self.console     = plugin.console
        self.irc_message = plugin.irc_message
        self.users       = InsensitiveDict()

    def signedOn(self):
        if have_ssl and isinstance(self.transport, TLSMemoryBIOProtocol):
            cert = self.transport.getPeerCertificate()
            fp = cert.digest("sha1")
            verified = "verified" if self.factory.parent.server_fingerprint else "unverified"
            self.console("irc: connected securely. server fingerprint: {} ({})".format(fp, verified))
        else:
            self.console("irc: connected")
        
        if self.ns_password:
            self.msg('NickServ', 'IDENTIFY %s' % self.ns_password)
        
        self.join(self.channel)

    def irc_JOIN(self, prefix, params):
        nick = prefix.split('!')[0]
        channel = params[-1]
        if nick == self.nickname:
            self.joined(channel)
        else:
            self.userJoined(prefix, channel)

    def joined(self, channel):
        self.console('irc: joined channel')
        self.factory.client = self
        def who(a):
            self.sendLine("WHO " + channel)
        self.factory.parent.repeating_task(who, 30, now=True)
    
    def isupport(self, args):
        self.compute_prefix_names()
        
    def compute_prefix_names(self):
        KNOWN_NAMES = {"o": "op", "h": "halfop", "v": "voice"}
        prefixdata = self.supported.getFeature("PREFIX", {"o": ("@", 0), "v": ("+", 1)}).items()
        op_priority = ([priority for mode, (prefix, priority) in prefixdata if mode == "o"] + [None])[0]
        self.prefixes, self.statuses, self.priority = {}, {}, {}

        for mode, (prefix, priority) in prefixdata:
            name = "?"
            if mode in KNOWN_NAMES:
                name = KNOWN_NAMES[mode]
            elif priority == 0:
                if op_priority == 2:
                    name = "owner"
                else:
                    name = "admin"
            else:
                name = "+" + mode
            self.prefixes[mode] = prefix
            self.statuses[prefix] = name
            self.priority[name] = priority
            self.priority[mode] = priority
            self.priority[prefix] = priority

    def parse_prefixes(self, user, nick, prefixes=''):
        status = []
        prefixdata = self.supported.getFeature("PREFIX", {"o": ("@", 0), "v": ("+", 1)}).items()
        for mode, (prefix, priority) in prefixdata:
            if prefix in prefixes + nick:
                nick = nick.replace(prefix, '')
                status.append((prefix, priority))
        if nick == self.nickname:
            return
        user.status = ''.join(t[0] for t in sorted(status, key=lambda t: t[1]))
    
    def irc_RPL_WHOREPLY(self, prefix, params):
        _, channel, username, host, server, nick, status, hg = params
        if nick == self.nickname:
            return
        hops, gecos = hg.split(' ', 1)
        user = IRCUser(self, nick)
        user.username = username
        user.hostname = host
        user.oper = '*' in status
        user.away = status[0] == 'G'
        self.users[nick] = user
        self.parse_prefixes(user, nick, status[1:].replace('*', ''))
    
    def modeChanged(self, user, channel, _set, modes, args):
        args = list(args)
        if channel.lower() != self.channel.lower():
            return
        for m, arg in zip(modes, args):
            if m in self.prefixes and arg != self.nickname:
                u = self.users.get(arg, None)
                if u:
                    u.status = u.status.replace(self.prefixes[m], '')
                    if _set:
                        u.status = ''.join(sorted(list(u.status + self.prefixes[m]),
                                                  key=lambda k: self.priority[k]))
    
    def userJoined(self, user, channel):
        nick = user.split('!')[0]
        user = IRCUser(self, nick)
        self.users[nick] = user
    
    def userRenamed(self, oldname, newname):
        if oldname not in self.users:
            return
        u = self.users[oldname]
        u.nick = newname
        self.users[newname] = u
        del self.users[oldname]
    
    def userLeft(self, user, channel):
        if user not in self.users:
            return
        del self.users[user]
    
    def userKicked(self, kickee, channel, kicker, message):
        if kickee not in self.users:
            return
        del self.users[kickee]
    
    def userQuit(self, user, quitMessage):
        if user not in self.users:
            return
        del self.users[user]

    def privmsg(self, user, channel, msg):
        if channel != self.channel:
            return
        if '!' not in user:
            return
        nick = user.split('!')[0]
        p = self.factory.parent
        
        if p.irc_chat_status and p.irc_chat_status in self.priority:
            priority = self.priority[p.irc_chat_status]
            u = self.users.get(nick, None)
            if not u or u.priority is None or u.priority > priority:
                return
        if p.irc_players_enabled and msg == p.irc_players_trigger:
            self.say(self.channel, p.irc_players_format.format(players=', '.join(p.players)))
        else:
            p.irc_message(nick, msg)

    def alterCollidedNick(self, nickname):
        return nickname + '_'

    def irc_relay(self, message):
        self.say(self.channel, message.encode('utf8'))
Beispiel #42
0
class Element(Node):
    nsprefixes = None
    create_attr = lambda k, v: (' ', k, '="', escape(v), '"')

    SINGLETONS = (
        'img', 'br', 'hr', 'base', 'meta', 'link', 'param',
        'area', 'input', 'col', 'basefont', 'isindex', 'frame')

    BLOCKELEMENTS = (
        'html', 'head', 'body', 'noscript', 'ins', 'del',
        'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'script',
        'ul', 'ol', 'dl', 'pre', 'hr', 'blockquote',
        'address', 'p', 'div', 'fieldset', 'table', 'tr',
        'form', 'object', 'fieldset', 'applet', 'map')

    NICEFORMATS = ('tr', 'ul', 'ol', 'head')

    def __init__(
        self, tagName, attributes=None, parentNode=None, filename=None,
        markpos=None, case_insensitive=1, namespace=None
    ):
        Node.__init__(self, parentNode)
        preserve_case = not case_insensitive
        tagName = tagName if preserve_case else tagName.lower()
        unescaped = unescape_dict(attributes or {})

        if case_insensitive:
            self.attributes = InsensitiveDict(unescaped, preserve=preserve_case)
        else:
            self.attributes = unescaped

        self.preserve_case = not case_insensitive
        self.case_insensitive = case_insensitive
        self.endTagName = self.nodeName = self.tagName = tagName
        self._filename = filename
        self._markpos = markpos
        self.namespace = namespace
        self.tag_is_blockelement = tagName in self.BLOCKELEMENTS
        self.tag_is_nice_format = tagName in self.NICEFORMATS
        self.tag_is_singleton = tagName.lower() in self.SINGLETONS

    def addPrefixes(self, pfxs):
        if self.nsprefixes is None:
            self.nsprefixes = pfxs
        else:
            self.nsprefixes.update(pfxs)

    def endTag(self, endTagName):
        if self.case_insensitive:
            endTagName = endTagName.lower()

        self.endTagName = endTagName

    def isEqualToElement(self, n):
        same_attrs = self.attributes == n.attributes

        if self.case_insensitive:
            eq = same_attrs and (self.nodeName.lower() == n.nodeName.lower())
        else:
            eq = same_attrs and (self.nodeName == n.nodeName)

        return eq

    def isEqualToNode(self, other):
        """
        Compare this element to C{other}.  If the C{nodeName}, C{namespace},
        C{attributes}, and C{childNodes} are all the same, return C{True},
        otherwise return C{False}.
        """
        return (
            self.nodeName.lower() == other.nodeName.lower() and
            self.namespace == other.namespace and
            self.attributes == other.attributes and
            Node.isEqualToNode(self, other))

    def cloneNode(self, deep=0, parent=None):
        clone = Element(
            self.tagName, parentNode=parent, namespace=self.namespace,
            case_insensitive=self.case_insensitive)

        clone.attributes.update(self.attributes)

        if deep:
            clone.childNodes = [
                child.cloneNode(1, clone) for child in self.childNodes]
        else:
            clone.childNodes = []

        return clone

    def getElementsByTagName(self, name):
        icase = self.case_insensitive
        return getElementsByTagName(self.childNodes, name, icase)

    def hasAttributes(self):
        return 1

    def getAttribute(self, name, default=None):
        return self.attributes.get(name, default)

    def getAttributeNS(self, ns, name, default=None):
        nsk = (ns, name)

        if nsk in self.attributes:
            return self.attributes[nsk]

        if ns == self.namespace:
            return self.attributes.get(name, default)

        return default

    def getAttributeNode(self, name):
        return _Attr(self.getAttribute(name), self)

    def setAttribute(self, name, attr):
        self.attributes[name] = attr

    def removeAttribute(self, name):
        if name in self.attributes:
            del self.attributes[name]

    def hasAttribute(self, name):
        return name in self.attributes

    def gen_prefixes(self, nsprefixes):
        for k, v in self.nsprefixes.items():
            if k not in nsprefixes:
                yield (k, v)

    def _writexml(self, namespace, nsprefixes, newl, indent):
        newprefixes = dict(self.gen_prefixes(nsprefixes))
        begin = [newl, indent, '<'] if self.tag_is_blockelement else ['<']
        is_same_namespace = self.namespace and namespace == self.namespace

        # Make a local for tracking what end tag will be used. If namespace
        # prefixes are involved, this will be changed to account for that
        # before it's actually used.
        endTagName = self.endTagName

        if not is_same_namespace and self.namespace in nsprefixes:
            # This tag's namespace already has a prefix bound to it. Use
            # that prefix.
            prefix = nsprefixes[self.namespace]
            begin.extend(prefix + ':' + self.tagName)

            # Also make sure we use it for the end tag.
            endTagName = prefix + ':' + self.endTagName
        elif not is_same_namespace:
            # This tag's namespace has no prefix bound to it. Change the
            # default namespace to this tag's namespace so we don't need
            # prefixes.  Alternatively, we could add a new prefix binding.
            # I'm not sure why the code was written one way rather than the
            # other. -exarkun
            begin.extend(self.tagName)
            begin.extend(self.create_attr("xmlns", self.namespace))

            # The default namespace just changed.  Make sure any children
            # know about this.
            namespace = self.namespace
        else:
            # This tag has no namespace or its namespace is already the default
            # namespace.  Nothing extra to do here.
            begin.extend(self.tagName)

        prefixes = ('p%s' % str(i) for i in it.count())

        for attr, val in sorted(self.attributes.items()):
            if val and isinstance(attr, tuple):
                ns, key = attr

                if ns in nsprefixes:
                    prefix = nsprefixes[ns]
                else:
                    newprefixes[ns] = prefix = next(prefixes)

                begin.extend(self.create_attr(prefix + ':' + key, val))
            elif val:
                begin.extend(self.create_attr(attr, val))

        return begin, namespace, endTagName, newprefixes

    def _write_child(self, stream, newl, newindent, **kwargs):
        for child in self.childNodes:
            if self.tag_is_blockelement and self.tag_is_nice_format:
                stream.write(''.join((newl, newindent)))

            child.writexml(stream, newl=newl, newindent=newindent, **kwargs)

    def writexml(self, stream, *args, **kwargs):
        """
        Serialize this L{Element} to the given stream.

        @param stream: A file-like object to which this L{Element} will be
            written.

        @param nsprefixes: A C{dict} mapping namespace URIs as C{str} to
            prefixes as C{str}.  This defines the prefixes which are already in
            scope in the document at the point at which this L{Element} exists.
            This is essentially an implementation detail for namespace support.
            Applications should not try to use it.

        @param namespace: The namespace URI as a C{str} which is the default at
            the point in the document at which this L{Element} exists.  This is
            essentially an implementation detail for namespace support.
            Applications should not try to use it.
        """
        indent = kwargs.get('indent', '')
        addindent = kwargs.get('addindent', '')
        newl = kwargs.get('newl', '')
        strip = kwargs.get('strip', 0)
        nsprefixes = kwargs.get('nsprefixes', {})
        namespace = kwargs.get('namespace', '')

        # this should never be necessary unless people start
        # changing .tagName on the fly(?)
        if self.case_insensitive:
            self.endTagName = self.tagName

        _args = (namespace, nsprefixes, newl, indent)
        begin, namespace, endTagName, newprefixes = self._writexml(*_args)

        for ns, prefix in newprefixes.items():
            if prefix:
                begin.extend(self.create_attr('xmlns:' + prefix, ns))

        newprefixes.update(nsprefixes)
        downprefixes = newprefixes
        stream.write(''.join(begin))

        if self.childNodes:
            stream.write(">")
            newindent = indent + addindent

            kwargs = {
                'newindent': newindent,
                'addindent': addindent,
                'newl': newl,
                'strip': strip,
                'downprefixes': downprefixes,
                'namespace': namespace}

            self._write_child(stream, newl, newindent, **kwargs)

            if self.tag_is_blockelement:
                stream.write(''.join((newl, indent)))

            stream.write(''.join(('</', endTagName, '>')))
        elif not self.tag_is_singleton:
            stream.write(''.join(('></', endTagName, '>')))
        else:
            stream.write(" />")

    def __repr__(self):
        rep = "Element(%s" % repr(self.nodeName)

        if self.attributes:
            rep += ", attributes=%r" % (self.attributes,)

        if self._filename:
            rep += ", filename=%r" % (self._filename,)

        if self._markpos:
            rep += ", markpos=%r" % (self._markpos,)

        return rep + ')'

    def __str__(self):
        rep = "<" + self.nodeName

        if self._filename or self._markpos:
            rep += " ("

        if self._filename:
            rep += repr(self._filename)

        if self._markpos:
            rep += " line %s column %s" % self._markpos

        if self._filename or self._markpos:
            rep += ")"

        for item in self.attributes.items():
            rep += " %s=%r" % item

        if self.hasChildNodes():
            rep += " >...</%s>" % self.nodeName
        else:
            rep += " />"

        return rep
Beispiel #43
0
class BaseLDAPEntry(object):
    implements(interfaces.ILDAPEntry)
    dn = None

    def __init__(self, dn, attributes={}):
        """

        Initialize the object.

        @param dn: Distinguished Name of the object, as a string.

        @param attributes: Attributes of the object. A dictionary of
        attribute types to list of attribute values.

        """
        self._attributes=InsensitiveDict()
        self.dn = distinguishedname.DistinguishedName(dn)

        for k,vs in attributes.items():
            if k not in self._attributes:
                self._attributes[k] = []
            self._attributes[k].extend(vs)

        for k,vs in self._attributes.items():
            self._attributes[k] = self.buildAttributeSet(k, vs)

    def buildAttributeSet(self, key, values):
        return attributeset.LDAPAttributeSet(key, values)

    def __getitem__(self, key):
        return self._attributes[key]

    def get(self, key, default=None):
        return self._attributes.get(key, default)

    def has_key(self, key):
        return key in self._attributes

    def __contains__(self, key):
        return self.has_key(key)

    def keys(self):
        return self._attributes.keys()

    def items(self):
        return self._attributes.items()

    def __str__(self):
        a=[]

        objectClasses = list(self.get('objectClass', []))
        objectClasses.sort()
        a.append(('objectClass', objectClasses))

        l=list(self.items())
        l.sort()
        for key, values in l:
            if key.lower() != 'objectclass':
                vs = list(values)
                vs.sort()
                a.append((key, vs))
        return ldif.asLDIF(self.dn, a)

    def __eq__(self, other):
        if not isinstance(other, BaseLDAPEntry):
            return 0
        if self.dn != other.dn:
            return 0

        my=self.keys()
        my.sort()
        its=other.keys()
        its.sort()
        if my!=its:
            return 0
        for key in my:
            myAttr=self[key]
            itsAttr=other[key]
            if myAttr!=itsAttr:
                return 0
        return 1

    def __ne__(self, other):
        return not self==other

    def __len__(self):
        return len(self.keys())

    def __nonzero__(self):
        return True

    def __repr__(self):
        x={}
        for key in self.keys():
            x[key]=self[key]
        keys=self.keys()
        keys.sort()
        a=[]
        for key in keys:
            a.append('%s: %s' % (repr(key), repr(list(self[key]))))
        attributes=', '.join(a)
        return '%s(%s, {%s})' % (
            self.__class__.__name__,
            repr(str(self.dn)),
            attributes)

    def diff(self, other):
        """
        Compute differences between this and another LDAP entry.

        @param other: An LDAPEntry to compare to.

        @return: None if equal, otherwise a ModifyOp that would make
        this entry look like other.
        """
        assert self.dn == other.dn
        if self == other:
            return None

        r = []

        myKeys = sets.Set(self.keys())
        otherKeys = sets.Set(other.keys())

        addedKeys = list(otherKeys - myKeys)
        addedKeys.sort() # for reproducability only
        for added in addedKeys:
            r.append(delta.Add(added, other[added]))

        deletedKeys = list(myKeys - otherKeys)
        deletedKeys.sort() # for reproducability only
        for deleted in deletedKeys:
            r.append(delta.Delete(deleted, self[deleted]))

        sharedKeys = list(myKeys & otherKeys)
        sharedKeys.sort() # for reproducability only
        for shared in sharedKeys:

            addedValues = list(other[shared] - self[shared])
            if addedValues:
                addedValues.sort() # for reproducability only
                r.append(delta.Add(shared, addedValues))

            deletedValues = list(self[shared] - other[shared])
            if deletedValues:
                deletedValues.sort() # for reproducability only
                r.append(delta.Delete(shared, deletedValues))

        return delta.ModifyOp(dn=self.dn, modifications=r)

    def bind(self, password):
        return defer.maybeDeferred(self._bind, password)

    def _bind(self, password):
        for digest in self.get('userPassword', ()):
            if digest.startswith('{SSHA}'):
                raw = base64.decodestring(digest[len('{SSHA}'):])
                salt = raw[20:]
                got = sshaDigest(password, salt)
                if got == digest:
                    return self
        raise ldaperrors.LDAPInvalidCredentials

    def hasMember(self, dn):
        for memberDN in self.get('member', []):
            if memberDN == dn:
                return True
        return False

    def __hash__(self):
        return hash(self.dn)
Beispiel #44
0
class HTTPClientFactory(protocol.ClientFactory):
    """Download a given URL.

    @type deferred: Deferred
    @ivar deferred: A Deferred that will fire when the content has
          been retrieved. Once this is fired, the ivars `status', `version',
          and `message' will be set.

    @type status: str
    @ivar status: The status of the response.

    @type version: str
    @ivar version: The version of the response.

    @type message: str
    @ivar message: The text message returned with the status.

    @type response_headers: dict
    @ivar response_headers: The headers that were specified in the
          response from the server.

    @type method: str
    @ivar method: The HTTP method to use in the request.  This should be one of
        OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, or CONNECT (case
        matters).  Other values may be specified if the server being contacted
        supports them.

    @type redirectLimit: int
    @ivar redirectLimit: The maximum number of HTTP redirects that can occur
          before it is assumed that the redirection is endless.

    @type afterFoundGet: C{bool}
    @ivar afterFoundGet: Deviate from the HTTP 1.1 RFC by handling redirects
        the same way as most web browsers; if the request method is POST and a
        302 status is encountered, the redirect is followed with a GET method

    @type _redirectCount: int
    @ivar _redirectCount: The current number of HTTP redirects encountered.

    @ivar _disconnectedDeferred: A L{Deferred} which only fires after the last
        connection associated with the request (redirects may cause multiple
        connections to be required) has closed.  The result Deferred will only
        fire after this Deferred, so that callers can be assured that there are
        no more event sources in the reactor once they get the result.
    """

    protocol = HTTPPageGetter

    url = None
    scheme = None
    host = ''
    port = None
    path = None

    def __init__(self, url, method='GET', postdata=None, headers=None,
                 agent="Twisted PageGetter", timeout=0, cookies=None,
                 followRedirect=True, redirectLimit=20,
                 afterFoundGet=False):
        self.followRedirect = followRedirect
        self.redirectLimit = redirectLimit
        self._redirectCount = 0
        self.timeout = timeout
        self.agent = agent
        self.afterFoundGet = afterFoundGet
        if cookies is None:
            cookies = {}
        self.cookies = cookies
        if headers is not None:
            self.headers = InsensitiveDict(headers)
        else:
            self.headers = InsensitiveDict()
        if postdata is not None:
            self.headers.setdefault('Content-Length', len(postdata))
            # just in case a broken http/1.1 decides to keep connection alive
            self.headers.setdefault("connection", "close")
        self.postdata = postdata
        self.method = method

        self.setURL(url)

        self.waiting = 1
        self._disconnectedDeferred = defer.Deferred()
        self.deferred = defer.Deferred()
        # Make sure the first callback on the result Deferred pauses the
        # callback chain until the request connection is closed.
        self.deferred.addBoth(self._waitForDisconnect)
        self.response_headers = None


    def _waitForDisconnect(self, passthrough):
        """
        Chain onto the _disconnectedDeferred, preserving C{passthrough}, so that
        the result is only available after the associated connection has been
        closed.
        """
        self._disconnectedDeferred.addCallback(lambda ignored: passthrough)
        return self._disconnectedDeferred


    def __repr__(self):
        return "<%s: %s>" % (self.__class__.__name__, self.url)

    def setURL(self, url):
        self.url = url
        scheme, host, port, path = _parse(url)
        if scheme and host:
            self.scheme = scheme
            self.host = host
            self.port = port
        self.path = path

    def buildProtocol(self, addr):
        p = protocol.ClientFactory.buildProtocol(self, addr)
        p.followRedirect = self.followRedirect
        p.afterFoundGet = self.afterFoundGet
        if self.timeout:
            timeoutCall = reactor.callLater(self.timeout, p.timeout)
            self.deferred.addBoth(self._cancelTimeout, timeoutCall)
        return p

    def _cancelTimeout(self, result, timeoutCall):
        if timeoutCall.active():
            timeoutCall.cancel()
        return result

    def gotHeaders(self, headers):
        self.response_headers = headers
        if headers.has_key('set-cookie'):
            for cookie in headers['set-cookie']:
                cookparts = cookie.split(';')
                cook = cookparts[0]
                cook.lstrip()
                k, v = cook.split('=', 1)
                self.cookies[k.lstrip()] = v.lstrip()

    def gotStatus(self, version, status, message):
        self.version, self.status, self.message = version, status, message

    def page(self, page):
        if self.waiting:
            self.waiting = 0
            self.deferred.callback(page)

    def noPage(self, reason):
        if self.waiting:
            self.waiting = 0
            self.deferred.errback(reason)

    def clientConnectionFailed(self, _, reason):
        """
        When a connection attempt fails, the request cannot be issued.  If no
        result has yet been provided to the result Deferred, provide the
        connection failure reason as an error result.
        """
        if self.waiting:
            self.waiting = 0
            # If the connection attempt failed, there is nothing more to
            # disconnect, so just fire that Deferred now.
            self._disconnectedDeferred.callback(None)
            self.deferred.errback(reason)
Beispiel #45
0
    def _create_message_from_headers(self,
                                     headers,
                                     auth_peer,
                                     me,
                                     known_inhs,
                                     must_know_peer=True,
                                     peer_proto=None):
        """
        Given the headers of the message, the "myself" reference
        to the receiving inhabitant, as well as the container of other
        known inhabitants, create a message.

        @param headers: The headers of the message.
        @type headers: InsensitiveDict

        @param auth_peer: What inhabitant authenticated as the originator of
                          the message?
        @type auth_peer: NoneType, AbstractInhabitant

        @param me: The inhabitant object of the system processing this message.
        @type me: AbstractInhabitant

        @param known_inhs: The dictionary-like mapping the UUIDs to other known
                           inhabitants of the system.

        @param must_know_peer: Whether we must know the peer beforehand to
                               process the message.
                               At the moment, it is used on the host, when it
                               receives the messages from unknown other hosts.
                               In the future, we ALWAYS must know the peer.
        @type must_know_peer: bool
        @todo: As soon as the Host->Host connections are preceded with the
               connection from the Node to the target Host (which notifies the
               target Host about the expected connection), C{must_know_peer}
               argument should be removed (and the code kept in the
               C{must_know_peer = True} position).

        @param peer_proto: The function which creates a peer object prototype
            depending upon the available information, if the peer is unknown.
            Default value is a subclass of C{AbstractInhabitant} constructor.
            Must accept all the usual C{AbstractInhabitant} constructor
            arguments.
        @todo: Remove peer_proto as long as must_know_peer is removed.

        @returns: The new message object.
        @rtype: AbstractMessage

        @raises MessageProcessingException: if the message could not be
                                            processed properly.
        """
        if peer_proto is None:
            peer_proto = AbstractInhabitant

        # Validate HTTP request
        pragma_data_list = headers.get('Pragma', None)
        if pragma_data_list is None or not pragma_data_list:
            raise MessageProcessingException('No message type header')

        assert isinstance(pragma_data_list, list)
        if len(pragma_data_list) != 1:
            raise MessageProcessingException(
                'Message type header is misconstructed')

        pragma_data = HTTPTransport.parse_pragma_header(pragma_data_list[0])

        # Validate again
        if 'msgtype' not in pragma_data:
            raise MessageProcessingException('No message type')
        if 'msgid' not in pragma_data:
            raise MessageProcessingException('No message ID')
        if 'from' not in pragma_data:
            raise MessageProcessingException('No source peer UUID')
        if 'to' not in pragma_data:
            raise MessageProcessingException('No destination peer UUID')
        if 'status_code' not in pragma_data:
            logger.warning('No status code!')
            # TODO: after some time (when all clients have been migrated),
            # change it to "raise MessageProcessingException()" below.
            # raise MessageProcessingException('No status code')

        # Validate build version
        if 'build' in pragma_data:
            _build_str = pragma_data['build']
            try:
                self.validate_build(_build_str)
            except MessageProcessingException:
                raise
            except Exception:
                logger.exception('Received the unparseable build version %r:',
                                 _build_str)
                raise MessageProcessingException(
                    'Incorrect build version: {}'.format(_build_str))

        # Validate status code
        try:
            status_code_txt = pragma_data.get('status_code', 0)
            int(status_code_txt)
        except:
            logger.error('Received the unparseable status_code %r:',
                         status_code_txt)
            # TODO: after some time (when all clients have been migrated),
            # change it to "raise MessageProcessingException()

        msg_type = pragma_data['msgtype']
        msg_uuid = uuid.UUID(pragma_data['msgid'])
        _from_uuid = uuid.UUID(pragma_data['from'])
        to_uuid = uuid.UUID(pragma_data['to'])
        status_code = int(pragma_data.get('status_code', 0))

        # Pre-validate origination peer
        if _from_uuid == NULL_UUID and auth_peer is None:
            raise MessageProcessingException(
                'Missing source UUID: {}'.format(_from_uuid))

        from_uuid = _from_uuid if _from_uuid != NULL_UUID \
                               else auth_peer.uuid
        # This still can be NULL_UUID at this point.
        if from_uuid == NULL_UUID:
            logger.debug('Totally no idea what host does %r have', auth_peer)

        # Validate termination UUID
        if me.uuid in (to_uuid, NULL_UUID):
            direct = True
            dst_inh = me
        elif to_uuid in known_inhs:
            direct = False
            dst_inh = known_inhs[to_uuid]
            logger.debug('Passthrough connection from %r to %r', from_uuid,
                         to_uuid)
        else:
            raise MessageProcessingException(
                'Unknown destination UUID: {}'.format(to_uuid))

        # Now create the AbstractMessage object according
        # to the received information.

        # Some more validation of the origination peer
        if auth_peer is not None:
            logger.debug('Assuming sender/auth_peer is %r', auth_peer)
            src_inh = auth_peer
        elif from_uuid not in known_inhs and must_know_peer:
            raise MessageProcessingException(
                'Unknown source UUID: {}'.format(from_uuid))
        else:
            logger.debug('Assuming sender/uuid is %r', from_uuid)
            # Try to get the peer somehow
            src_inh = known_inhs.get(from_uuid, None)
            if src_inh is None:
                src_inh = peer_proto(uuid=from_uuid)

        logger.debug('Finally, sender is %r', src_inh)

        assert self.tr_manager is not None
        message = self.tr_manager.create_message(name=msg_type,
                                                 src=src_inh,
                                                 dst=dst_inh,
                                                 uuid=msg_uuid,
                                                 direct=direct,
                                                 status_code=status_code)

        message.init_from_headers(InsensitiveDict(headers))

        return message
Beispiel #46
0
# enable: W9602

# an example of call has_key on a dict
# a warning should be generated

if {}.has_key("bar"):
    pass

foo = {}

if foo.has_key("bar"):
    pass

# an example of call has_key on a existing class
# no warnings should be showed in this case
from twisted.python.util import InsensitiveDict

bar = InsensitiveDict()
if bar.has_key("bar"):
    pass

# an example of call has_key on a unknown object
# no warnings should be showed as we do not know what it is

result = baz.has_key("bar")
Beispiel #47
0
class HTTPClientFactory(protocol.ClientFactory):
    """Download a given URL.

    @type deferred: Deferred
    @ivar deferred: A Deferred that will fire when the content has
          been retrieved. Once this is fired, the ivars `status', `version',
          and `message' will be set.

    @type status: str
    @ivar status: The status of the response.

    @type version: str
    @ivar version: The version of the response.

    @type message: str
    @ivar message: The text message returned with the status.

    @type response_headers: dict
    @ivar response_headers: The headers that were specified in the
          response from the server.
    """

    protocol = HTTPPageGetter

    url = None
    scheme = None
    host = ''
    port = None
    path = None

    def __init__(self,
                 url,
                 method='GET',
                 postdata=None,
                 headers=None,
                 agent="Twisted PageGetter",
                 timeout=0,
                 cookies=None,
                 followRedirect=1):
        self.protocol.followRedirect = followRedirect
        self.timeout = timeout
        self.agent = agent

        if cookies is None:
            cookies = {}
        self.cookies = cookies
        if headers is not None:
            self.headers = InsensitiveDict(headers)
        else:
            self.headers = InsensitiveDict()
        if postdata is not None:
            self.headers.setdefault('Content-Length', len(postdata))
            # just in case a broken http/1.1 decides to keep connection alive
            self.headers.setdefault("connection", "close")
        self.postdata = postdata
        self.method = method

        self.setURL(url)

        self.waiting = 1
        self.deferred = defer.Deferred()
        self.response_headers = None

    def __repr__(self):
        return "<%s: %s>" % (self.__class__.__name__, self.url)

    def setURL(self, url):
        self.url = url
        scheme, host, port, path = _parse(url)
        if scheme and host:
            self.scheme = scheme
            self.host = host
            self.port = port
        self.path = path

    def buildProtocol(self, addr):
        p = protocol.ClientFactory.buildProtocol(self, addr)
        if self.timeout:
            timeoutCall = reactor.callLater(self.timeout, p.timeout)
            self.deferred.addBoth(self._cancelTimeout, timeoutCall)
        return p

    def _cancelTimeout(self, result, timeoutCall):
        if timeoutCall.active():
            timeoutCall.cancel()
        return result

    def gotHeaders(self, headers):
        self.response_headers = headers
        if headers.has_key('set-cookie'):
            for cookie in headers['set-cookie']:
                cookparts = cookie.split(';')
                cook = cookparts[0]
                cook.lstrip()
                k, v = cook.split('=', 1)
                self.cookies[k.lstrip()] = v.lstrip()

    def gotStatus(self, version, status, message):
        self.version, self.status, self.message = version, status, message

    def page(self, page):
        if self.waiting:
            self.waiting = 0
            self.deferred.callback(page)

    def noPage(self, reason):
        if self.waiting:
            self.waiting = 0
            self.deferred.errback(reason)

    def clientConnectionFailed(self, _, reason):
        if self.waiting:
            self.waiting = 0
            self.deferred.errback(reason)
Beispiel #48
0
class Element(Node):

    preserveCase = 0
    caseInsensitive = 1
    nsprefixes = None

    def __init__(self,
                 tagName,
                 attributes=None,
                 parentNode=None,
                 filename=None,
                 markpos=None,
                 caseInsensitive=1,
                 preserveCase=0,
                 namespace=None):
        Node.__init__(self, parentNode)
        self.preserveCase = preserveCase or not caseInsensitive
        self.caseInsensitive = caseInsensitive
        if not preserveCase:
            tagName = tagName.lower()
        if attributes is None:
            self.attributes = {}
        else:
            self.attributes = attributes
            for k, v in self.attributes.items():
                self.attributes[k] = unescape(v)

        if caseInsensitive:
            self.attributes = InsensitiveDict(self.attributes,
                                              preserve=preserveCase)

        self.endTagName = self.nodeName = self.tagName = tagName
        self._filename = filename
        self._markpos = markpos
        self.namespace = namespace

    def addPrefixes(self, pfxs):
        if self.nsprefixes is None:
            self.nsprefixes = pfxs
        else:
            self.nsprefixes.update(pfxs)

    def endTag(self, endTagName):
        if not self.preserveCase:
            endTagName = endTagName.lower()
        self.endTagName = endTagName

    def isEqualToElement(self, n):
        if self.caseInsensitive:
            return ((self.attributes == n.attributes)
                    and (self.nodeName.lower() == n.nodeName.lower()))
        return (self.attributes == n.attributes) and (self.nodeName
                                                      == n.nodeName)

    def isEqualToNode(self, other):
        """
        Compare this element to C{other}.  If the C{nodeName}, C{namespace},
        C{attributes}, and C{childNodes} are all the same, return C{True},
        otherwise return C{False}.
        """
        return (self.nodeName.lower() == other.nodeName.lower()
                and self.namespace == other.namespace
                and self.attributes == other.attributes
                and Node.isEqualToNode(self, other))

    def cloneNode(self, deep=0, parent=None):
        clone = Element(self.tagName,
                        parentNode=parent,
                        namespace=self.namespace,
                        preserveCase=self.preserveCase,
                        caseInsensitive=self.caseInsensitive)
        clone.attributes.update(self.attributes)
        if deep:
            clone.childNodes = [
                child.cloneNode(1, clone) for child in self.childNodes
            ]
        else:
            clone.childNodes = []
        return clone

    def getElementsByTagName(self, name):
        if self.caseInsensitive:
            return getElementsByTagNameNoCase(self, name)
        return getElementsByTagName(self, name)

    def hasAttributes(self):
        return 1

    def getAttribute(self, name, default=None):
        return self.attributes.get(name, default)

    def getAttributeNS(self, ns, name, default=None):
        nsk = (ns, name)
        if self.attributes.has_key(nsk):
            return self.attributes[nsk]
        if ns == self.namespace:
            return self.attributes.get(name, default)
        return default

    def getAttributeNode(self, name):
        return _Attr(self.getAttribute(name), self)

    def setAttribute(self, name, attr):
        self.attributes[name] = attr

    def removeAttribute(self, name):
        if name in self.attributes:
            del self.attributes[name]

    def hasAttribute(self, name):
        return name in self.attributes

    def writexml(self,
                 stream,
                 indent='',
                 addindent='',
                 newl='',
                 strip=0,
                 nsprefixes={},
                 namespace=''):
        # write beginning
        ALLOWSINGLETON = ('img', 'br', 'hr', 'base', 'meta', 'link', 'param',
                          'area', 'input', 'col', 'basefont', 'isindex',
                          'frame')
        BLOCKELEMENTS = ('html', 'head', 'body', 'noscript', 'ins', 'del',
                         'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'script', 'ul',
                         'ol', 'dl', 'pre', 'hr', 'blockquote', 'address', 'p',
                         'div', 'fieldset', 'table', 'tr', 'form', 'object',
                         'fieldset', 'applet', 'map')
        FORMATNICELY = ('tr', 'ul', 'ol', 'head')

        # this should never be necessary unless people start
        # changing .tagName on the fly(?)
        if not self.preserveCase:
            self.endTagName = self.tagName
        w = stream.write
        if self.nsprefixes:
            newprefixes = self.nsprefixes.copy()
            for ns in nsprefixes.keys():
                if ns in newprefixes:
                    del newprefixes[ns]
        else:
            newprefixes = {}

        begin = ['<']
        if self.tagName in BLOCKELEMENTS:
            begin = [newl, indent] + begin
        bext = begin.extend
        writeattr = lambda _atr, _val: bext(
            (' ', _atr, '="', escape(_val), '"'))
        if namespace != self.namespace and self.namespace is not None:
            if nsprefixes.has_key(self.namespace):
                prefix = nsprefixes[self.namespace]
                bext(prefix + ':' + self.tagName)
            else:
                bext(self.tagName)
                writeattr("xmlns", self.namespace)
        else:
            bext(self.tagName)
        j = ''.join
        for attr, val in self.attributes.iteritems():
            if isinstance(attr, tuple):
                ns, key = attr
                if nsprefixes.has_key(ns):
                    prefix = nsprefixes[ns]
                else:
                    prefix = genprefix()
                    newprefixes[ns] = prefix
                assert val is not None
                writeattr(prefix + ':' + key, val)
            else:
                assert val is not None
                writeattr(attr, val)
        if newprefixes:
            for ns, prefix in newprefixes.iteritems():
                if prefix:
                    writeattr('xmlns:' + prefix, ns)
            newprefixes.update(nsprefixes)
            downprefixes = newprefixes
        else:
            downprefixes = nsprefixes
        w(j(begin))
        if self.childNodes:
            w(">")
            newindent = indent + addindent
            for child in self.childNodes:
                if self.tagName in BLOCKELEMENTS and \
                   self.tagName in FORMATNICELY:
                    w(j((newl, newindent)))
                child.writexml(stream, newindent, addindent, newl, strip,
                               downprefixes, self.namespace)
            if self.tagName in BLOCKELEMENTS:
                w(j((newl, indent)))
            w(j(("</", self.endTagName, '>')))

        elif self.tagName.lower() not in ALLOWSINGLETON:
            w(j(('></', self.endTagName, '>')))
        else:
            w(" />")

    def __repr__(self):
        rep = "Element(%s" % repr(self.nodeName)
        if self.attributes:
            rep += ", attributes=%r" % (self.attributes, )
        if self._filename:
            rep += ", filename=%r" % (self._filename, )
        if self._markpos:
            rep += ", markpos=%r" % (self._markpos, )
        return rep + ')'

    def __str__(self):
        rep = "<" + self.nodeName
        if self._filename or self._markpos:
            rep += " ("
        if self._filename:
            rep += repr(self._filename)
        if self._markpos:
            rep += " line %s column %s" % self._markpos
        if self._filename or self._markpos:
            rep += ")"
        for item in self.attributes.items():
            rep += " %s=%r" % item
        if self.hasChildNodes():
            rep += " >...</%s>" % self.nodeName
        else:
            rep += " />"
        return rep
Beispiel #49
0
class Element(Node):

    preserveCase = 0
    caseInsensitive = 1
    nsprefixes = None

    def __init__(self,
                 tagName,
                 attributes=None,
                 parentNode=None,
                 filename=None,
                 markpos=None,
                 caseInsensitive=1,
                 preserveCase=0,
                 namespace=None):
        Node.__init__(self, parentNode)
        self.preserveCase = preserveCase or not caseInsensitive
        self.caseInsensitive = caseInsensitive
        if not preserveCase:
            tagName = tagName.lower()
        if attributes is None:
            self.attributes = {}
        else:
            self.attributes = attributes
            for k, v in self.attributes.items():
                self.attributes[k] = unescape(v)

        if caseInsensitive:
            self.attributes = InsensitiveDict(self.attributes,
                                              preserve=preserveCase)

        self.endTagName = self.nodeName = self.tagName = tagName
        self._filename = filename
        self._markpos = markpos
        self.namespace = namespace

    def addPrefixes(self, pfxs):
        if self.nsprefixes is None:
            self.nsprefixes = pfxs
        else:
            self.nsprefixes.update(pfxs)

    def endTag(self, endTagName):
        if not self.preserveCase:
            endTagName = endTagName.lower()
        self.endTagName = endTagName

    def isEqualToElement(self, n):
        if self.caseInsensitive:
            return ((self.attributes == n.attributes)
                    and (self.nodeName.lower() == n.nodeName.lower()))
        return (self.attributes == n.attributes) and (self.nodeName
                                                      == n.nodeName)

    def isEqualToNode(self, other):
        """
        Compare this element to C{other}.  If the C{nodeName}, C{namespace},
        C{attributes}, and C{childNodes} are all the same, return C{True},
        otherwise return C{False}.
        """
        return (self.nodeName.lower() == other.nodeName.lower()
                and self.namespace == other.namespace
                and self.attributes == other.attributes
                and Node.isEqualToNode(self, other))

    def cloneNode(self, deep=0, parent=None):
        clone = Element(self.tagName,
                        parentNode=parent,
                        namespace=self.namespace,
                        preserveCase=self.preserveCase,
                        caseInsensitive=self.caseInsensitive)
        clone.attributes.update(self.attributes)
        if deep:
            clone.childNodes = [
                child.cloneNode(1, clone) for child in self.childNodes
            ]
        else:
            clone.childNodes = []
        return clone

    def getElementsByTagName(self, name):
        if self.caseInsensitive:
            return getElementsByTagNameNoCase(self, name)
        return getElementsByTagName(self, name)

    def hasAttributes(self):
        return 1

    def getAttribute(self, name, default=None):
        return self.attributes.get(name, default)

    def getAttributeNS(self, ns, name, default=None):
        nsk = (ns, name)
        if nsk in self.attributes:
            return self.attributes[nsk]
        if ns == self.namespace:
            return self.attributes.get(name, default)
        return default

    def getAttributeNode(self, name):
        return _Attr(self.getAttribute(name), self)

    def setAttribute(self, name, attr):
        self.attributes[name] = attr

    def removeAttribute(self, name):
        if name in self.attributes:
            del self.attributes[name]

    def hasAttribute(self, name):
        return name in self.attributes

    def writexml(self,
                 stream,
                 indent='',
                 addindent='',
                 newl='',
                 strip=0,
                 nsprefixes={},
                 namespace=''):
        """
        Serialize this L{Element} to the given stream.

        @param stream: A file-like object to which this L{Element} will be
            written.

        @param nsprefixes: A C{dict} mapping namespace URIs as C{str} to
            prefixes as C{str}.  This defines the prefixes which are already in
            scope in the document at the point at which this L{Element} exists.
            This is essentially an implementation detail for namespace support.
            Applications should not try to use it.

        @param namespace: The namespace URI as a C{str} which is the default at
            the point in the document at which this L{Element} exists.  This is
            essentially an implementation detail for namespace support.
            Applications should not try to use it.
        """
        # write beginning
        ALLOWSINGLETON = ('img', 'br', 'hr', 'base', 'meta', 'link', 'param',
                          'area', 'input', 'col', 'basefont', 'isindex',
                          'frame')
        BLOCKELEMENTS = ('html', 'head', 'body', 'noscript', 'ins', 'del',
                         'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'script', 'ul',
                         'ol', 'dl', 'pre', 'hr', 'blockquote', 'address', 'p',
                         'div', 'fieldset', 'table', 'tr', 'form', 'object',
                         'fieldset', 'applet', 'map')
        FORMATNICELY = ('tr', 'ul', 'ol', 'head')

        # this should never be necessary unless people start
        # changing .tagName on the fly(?)
        if not self.preserveCase:
            self.endTagName = self.tagName
        w = stream.write
        if self.nsprefixes:
            newprefixes = self.nsprefixes.copy()
            for ns in nsprefixes.keys():
                if ns in newprefixes:
                    del newprefixes[ns]
        else:
            newprefixes = {}

        begin = ['<']
        if self.tagName in BLOCKELEMENTS:
            begin = [newl, indent] + begin
        bext = begin.extend
        writeattr = lambda _atr, _val: bext(
            (' ', _atr, '="', escape(_val), '"'))

        # Make a local for tracking what end tag will be used.  If namespace
        # prefixes are involved, this will be changed to account for that
        # before it's actually used.
        endTagName = self.endTagName

        if namespace != self.namespace and self.namespace is not None:
            # If the current default namespace is not the namespace of this tag
            # (and this tag has a namespace at all) then we'll write out
            # something related to namespaces.
            if self.namespace in nsprefixes:
                # This tag's namespace already has a prefix bound to it.  Use
                # that prefix.
                prefix = nsprefixes[self.namespace]
                bext(prefix + ':' + self.tagName)
                # Also make sure we use it for the end tag.
                endTagName = prefix + ':' + self.endTagName
            else:
                # This tag's namespace has no prefix bound to it.  Change the
                # default namespace to this tag's namespace so we don't need
                # prefixes.  Alternatively, we could add a new prefix binding.
                # I'm not sure why the code was written one way rather than the
                # other. -exarkun
                bext(self.tagName)
                writeattr("xmlns", self.namespace)
                # The default namespace just changed.  Make sure any children
                # know about this.
                namespace = self.namespace
        else:
            # This tag has no namespace or its namespace is already the default
            # namespace.  Nothing extra to do here.
            bext(self.tagName)

        j = ''.join
        for attr, val in sorted(self.attributes.items()):
            if isinstance(attr, tuple):
                ns, key = attr
                if ns in nsprefixes:
                    prefix = nsprefixes[ns]
                else:
                    prefix = genprefix()
                    newprefixes[ns] = prefix
                assert val is not None
                writeattr(prefix + ':' + key, val)
            else:
                assert val is not None
                writeattr(attr, val)
        if newprefixes:
            for ns, prefix in newprefixes.iteritems():
                if prefix:
                    writeattr('xmlns:' + prefix, ns)
            newprefixes.update(nsprefixes)
            downprefixes = newprefixes
        else:
            downprefixes = nsprefixes
        w(j(begin))
        if self.childNodes:
            w(">")
            newindent = indent + addindent
            for child in self.childNodes:
                if self.tagName in BLOCKELEMENTS and \
                   self.tagName in FORMATNICELY:
                    w(j((newl, newindent)))
                child.writexml(stream, newindent, addindent, newl, strip,
                               downprefixes, namespace)
            if self.tagName in BLOCKELEMENTS:
                w(j((newl, indent)))
            w(j(('</', endTagName, '>')))
        elif self.tagName.lower() not in ALLOWSINGLETON:
            w(j(('></', endTagName, '>')))
        else:
            w(" />")

    def __repr__(self):
        rep = "Element(%s" % repr(self.nodeName)
        if self.attributes:
            rep += ", attributes=%r" % (self.attributes, )
        if self._filename:
            rep += ", filename=%r" % (self._filename, )
        if self._markpos:
            rep += ", markpos=%r" % (self._markpos, )
        return rep + ')'

    def __str__(self):
        rep = "<" + self.nodeName
        if self._filename or self._markpos:
            rep += " ("
        if self._filename:
            rep += repr(self._filename)
        if self._markpos:
            rep += " line %s column %s" % self._markpos
        if self._filename or self._markpos:
            rep += ")"
        for item in self.attributes.items():
            rep += " %s=%r" % item
        if self.hasChildNodes():
            rep += " >...</%s>" % self.nodeName
        else:
            rep += " />"
        return rep
Beispiel #50
0
class BaseLDAPEntry(WireStrAlias):
    dn = None
    _object_class_keys = set(get_strings('objectClass'))
    _object_class_lower_keys = set(get_strings('objectclass'))
    _user_password_keys = set(get_strings('userPassword'))

    def __init__(self, dn, attributes={}):
        """

        Initialize the object.

        @param dn: Distinguished Name of the object, as a string.

        @param attributes: Attributes of the object. A dictionary of
        attribute types to list of attribute values.

        """
        self._attributes = InsensitiveDict()
        self.dn = distinguishedname.DistinguishedName(dn)

        for k, vs in attributes.items():
            if k not in self._attributes:
                self._attributes[k] = []
            self._attributes[k].extend(vs)

        for k, vs in self._attributes.items():
            self._attributes[k] = self.buildAttributeSet(k, vs)

    def buildAttributeSet(self, key, values):
        return attributeset.LDAPAttributeSet(key, values)

    def __getitem__(self, key):
        for k in get_strings(key):
            if k in self._attributes:
                return self._attributes[k]
        raise KeyError(key)

    def get(self, key, default=None):
        for k in get_strings(key):
            if k in self._attributes:
                return self._attributes[k]
        return default

    def has_key(self, key):
        for k in get_strings(key):
            if k in self._attributes:
                return True
        return False

    def __contains__(self, key):
        return self.has_key(key)

    def __iter__(self):
        for key in self._attributes.iterkeys():
            yield key

    def keys(self):
        a = []
        for key in self._object_class_keys:
            if key in self._attributes:
                a.append(key)
        l = list(self._attributes.keys())
        l.sort(key=to_bytes)
        for key in l:
            if key.lower() not in self._object_class_lower_keys:
                a.append(key)
        return a

    def items(self):
        a = []

        for key in self._object_class_keys:
            objectClasses = list(self._attributes.get(key, []))
            objectClasses.sort(key=to_bytes)
            if objectClasses:
                a.append((key, objectClasses))

        l = list(self._attributes.items())
        l.sort(key=lambda x: to_bytes(x[0]))
        for key, values in l:
            if key.lower() not in self._object_class_lower_keys:
                vs = list(values)
                vs.sort()
                a.append((key, vs))

        return a

    def toWire(self):
        a = []

        for key in self._object_class_keys:
            objectClasses = list(self._attributes.get(key, []))
            objectClasses.sort(key=to_bytes)
            a.append((key, objectClasses))

        items_gen = ((key, self[key]) for key in self)
        items = sorted(items_gen, key=lambda x: to_bytes(x[0]))
        for key, values in items:
            if key.lower() not in self._object_class_lower_keys:
                vs = list(values)
                vs.sort()
                a.append((key, vs))
        return ldif.asLDIF(self.dn.getText(), a)

    def getLDIF(self):
        return self.toWire().decode('utf-8')

    def __eq__(self, other):
        if not isinstance(other, BaseLDAPEntry):
            return NotImplemented
        if self.dn != other.dn:
            return 0

        my = sorted((key for key in self), key=to_bytes)
        its = sorted((key for key in other), key=to_bytes)
        if my != its:
            return 0
        for key in my:
            myAttr = self[key]
            itsAttr = other[key]
            if myAttr != itsAttr:
                return 0
        return 1

    def __ne__(self, other):
        return not self == other

    def __len__(self):
        return len(self.keys())

    def __bool__(self):
        return True

    def __nonzero__(self):
        return self.__bool__()

    def __repr__(self):
        keys = sorted((key for key in self), key=to_bytes)
        a = []
        for key in keys:
            a.append('%s: %s' % (repr(key), repr(list(self[key]))))
        attributes = ', '.join(a)
        dn = to_bytes(self.dn.getText()) if six.PY2 else self.dn.getText()
        return '%s(%s, {%s})' % (self.__class__.__name__, repr(dn), attributes)

    def diff(self, other):
        """
        Compute differences between this and another LDAP entry.

        @param other: An LDAPEntry to compare to.

        @return: None if equal, otherwise a ModifyOp that would make
        this entry look like other.
        """
        assert self.dn == other.dn
        if self == other:
            return None

        r = []

        myKeys = set(key for key in self)
        otherKeys = set(key for key in other)

        addedKeys = list(otherKeys - myKeys)
        addedKeys.sort(key=to_bytes)  # for reproducability only
        for added in addedKeys:
            r.append(delta.Add(added, other[added]))

        deletedKeys = list(myKeys - otherKeys)
        deletedKeys.sort(key=to_bytes)  # for reproducability only
        for deleted in deletedKeys:
            r.append(delta.Delete(deleted, self[deleted]))

        sharedKeys = list(myKeys & otherKeys)
        sharedKeys.sort(key=to_bytes)  # for reproducability only
        for shared in sharedKeys:

            addedValues = list(other[shared] - self[shared])
            if addedValues:
                addedValues.sort(key=to_bytes)  # for reproducability only
                r.append(delta.Add(shared, addedValues))

            deletedValues = list(self[shared] - other[shared])
            if deletedValues:
                deletedValues.sort(key=to_bytes)  # for reproducability only
                r.append(delta.Delete(shared, deletedValues))

        return delta.ModifyOp(dn=self.dn, modifications=r)

    def bind(self, password):
        return defer.maybeDeferred(self._bind, password)

    def _bind(self, password):
        password = to_bytes(password)
        for key in self._user_password_keys:
            for digest in self.get(key, ()):
                digest = to_bytes(digest)
                if digest.startswith(b'{SSHA}'):
                    raw = base64.decodestring(digest[len(b'{SSHA}'):])
                    salt = raw[20:]
                    got = sshaDigest(password, salt)
                    if got == digest:
                        return self
                else:
                    # Plaintext
                    if digest == password:
                        return self
        raise ldaperrors.LDAPInvalidCredentials()

    def hasMember(self, dn):
        for memberDN in self.get('member', []):
            if memberDN == dn:
                return True
        return False

    def __hash__(self):
        # FIXME:https://github.com/twisted/ldaptor/issues/101
        # The hash should take into consideration any attribute used to
        # decide the equality.
        return hash(self.dn)
Beispiel #51
0
class HTTPClientFactory(protocol.ClientFactory):
    """Download a given URL.

    @type deferred: Deferred
    @ivar deferred: A Deferred that will fire when the content has
          been retrieved. Once this is fired, the ivars `status', `version',
          and `message' will be set.

    @type status: str
    @ivar status: The status of the response.

    @type version: str
    @ivar version: The version of the response.

    @type message: str
    @ivar message: The text message returned with the status.

    @type response_headers: dict
    @ivar response_headers: The headers that were specified in the
          response from the server.

    @type method: str
    @ivar method: The HTTP method to use in the request.  This should be one of
        OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, or CONNECT (case
        matters).  Other values may be specified if the server being contacted
        supports them.

    @type redirectLimit: int
    @ivar redirectLimit: The maximum number of HTTP redirects that can occur
          before it is assumed that the redirection is endless.

    @type afterFoundGet: C{bool}
    @ivar afterFoundGet: Deviate from the HTTP 1.1 RFC by handling redirects
        the same way as most web browsers; if the request method is POST and a
        302 status is encountered, the redirect is followed with a GET method

    @type _redirectCount: int
    @ivar _redirectCount: The current number of HTTP redirects encountered.
    """

    protocol = HTTPPageGetter

    url = None
    scheme = None
    host = ""
    port = None
    path = None

    def __init__(
        self,
        url,
        method="GET",
        postdata=None,
        headers=None,
        agent="Twisted PageGetter",
        timeout=0,
        cookies=None,
        followRedirect=True,
        redirectLimit=20,
        afterFoundGet=False,
    ):
        self.followRedirect = followRedirect
        self.redirectLimit = redirectLimit
        self._redirectCount = 0
        self.timeout = timeout
        self.agent = agent
        self.afterFoundGet = afterFoundGet
        if cookies is None:
            cookies = {}
        self.cookies = cookies
        if headers is not None:
            self.headers = InsensitiveDict(headers)
        else:
            self.headers = InsensitiveDict()
        if postdata is not None:
            self.headers.setdefault("Content-Length", len(postdata))
            # just in case a broken http/1.1 decides to keep connection alive
            self.headers.setdefault("connection", "close")
        self.postdata = postdata
        self.method = method

        self.setURL(url)

        self.waiting = 1
        self.deferred = defer.Deferred()
        self.response_headers = None

    def __repr__(self):
        return "<%s: %s>" % (self.__class__.__name__, self.url)

    def setURL(self, url):
        self.url = url
        scheme, host, port, path = _parse(url)
        if scheme and host:
            self.scheme = scheme
            self.host = host
            self.port = port
        self.path = path

    def buildProtocol(self, addr):
        p = protocol.ClientFactory.buildProtocol(self, addr)
        p.followRedirect = self.followRedirect
        p.afterFoundGet = self.afterFoundGet
        if self.timeout:
            timeoutCall = reactor.callLater(self.timeout, p.timeout)
            self.deferred.addBoth(self._cancelTimeout, timeoutCall)
        return p

    def _cancelTimeout(self, result, timeoutCall):
        if timeoutCall.active():
            timeoutCall.cancel()
        return result

    def gotHeaders(self, headers):
        self.response_headers = headers
        if headers.has_key("set-cookie"):
            for cookie in headers["set-cookie"]:
                cookparts = cookie.split(";")
                cook = cookparts[0]
                cook.lstrip()
                k, v = cook.split("=", 1)
                self.cookies[k.lstrip()] = v.lstrip()

    def gotStatus(self, version, status, message):
        self.version, self.status, self.message = version, status, message

    def page(self, page):
        if self.waiting:
            self.waiting = 0
            self.deferred.callback(page)

    def noPage(self, reason):
        if self.waiting:
            self.waiting = 0
            self.deferred.errback(reason)

    def clientConnectionFailed(self, _, reason):
        if self.waiting:
            self.waiting = 0
            self.deferred.errback(reason)
Beispiel #52
0
class BaseLDAPEntry(object):
    implements(interfaces.ILDAPEntry)
    dn = None

    def __init__(self, dn, attributes={}):
        """

        Initialize the object.

        @param dn: Distinguished Name of the object, as a string.

        @param attributes: Attributes of the object. A dictionary of
        attribute types to list of attribute values.

        """
        self._attributes=InsensitiveDict()
        self.dn = distinguishedname.DistinguishedName(dn)

        for k,vs in attributes.items():
            if k not in self._attributes:
                self._attributes[k] = []
            self._attributes[k].extend(vs)

        for k,vs in self._attributes.items():
            self._attributes[k] = self.buildAttributeSet(k, vs)

    def buildAttributeSet(self, key, values):
        return attributeset.LDAPAttributeSet(key, values)

    def __getitem__(self, key):
        return self._attributes[key]

    def get(self, key, default=None):
        return self._attributes.get(key, default)

    def has_key(self, key):
        return key in self._attributes

    def __contains__(self, key):
        return self.has_key(key)

    def keys(self):
        a = []
        if self.get('objectClass'):
            a.append('objectClass')
        l=list(self._attributes.keys())
        l.sort()
        for key in l:
            if key.lower() != 'objectclass':
                a.append(key)
        return a

    def items(self):
        a=[]
        objectClasses = list(self.get('objectClass', []))
        objectClasses.sort()
        if objectClasses:
            a.append(('objectClass', objectClasses))

        l=list(self._attributes.items())
        l.sort()
        for key, values in l:
            if key.lower() != 'objectclass':
                vs = list(values)
                vs.sort()
                a.append((key, vs))

        return a

    def __str__(self):
        a=[]

        objectClasses = list(self.get('objectClass', []))
        objectClasses.sort()
        a.append(('objectClass', objectClasses))

        l=list(self.items())
        l.sort()
        for key, values in l:
            if key.lower() != 'objectclass':
                vs = list(values)
                vs.sort()
                a.append((key, vs))
        return ldif.asLDIF(self.dn, a)

    def __eq__(self, other):
        if not isinstance(other, BaseLDAPEntry):
            return 0
        if self.dn != other.dn:
            return 0

        my=self.keys()
        my.sort()
        its=other.keys()
        its.sort()
        if my!=its:
            return 0
        for key in my:
            myAttr=self[key]
            itsAttr=other[key]
            if myAttr!=itsAttr:
                return 0
        return 1

    def __ne__(self, other):
        return not self==other

    def __len__(self):
        return len(self.keys())

    def __nonzero__(self):
        return True

    def __repr__(self):
        x={}
        for key in self.keys():
            x[key]=self[key]
        keys=self.keys()
        keys.sort()
        a=[]
        for key in keys:
            a.append('%s: %s' % (repr(key), repr(list(self[key]))))
        attributes=', '.join(a)
        return '%s(%s, {%s})' % (
            self.__class__.__name__,
            repr(str(self.dn)),
            attributes)

    def diff(self, other):
        """
        Compute differences between this and another LDAP entry.

        @param other: An LDAPEntry to compare to.

        @return: None if equal, otherwise a ModifyOp that would make
        this entry look like other.
        """
        assert self.dn == other.dn
        if self == other:
            return None

        r = []

        myKeys = set(self.keys())
        otherKeys = set(other.keys())

        addedKeys = list(otherKeys - myKeys)
        addedKeys.sort() # for reproducability only
        for added in addedKeys:
            r.append(delta.Add(added, other[added]))

        deletedKeys = list(myKeys - otherKeys)
        deletedKeys.sort() # for reproducability only
        for deleted in deletedKeys:
            r.append(delta.Delete(deleted, self[deleted]))

        sharedKeys = list(myKeys & otherKeys)
        sharedKeys.sort() # for reproducability only
        for shared in sharedKeys:

            addedValues = list(other[shared] - self[shared])
            if addedValues:
                addedValues.sort() # for reproducability only
                r.append(delta.Add(shared, addedValues))

            deletedValues = list(self[shared] - other[shared])
            if deletedValues:
                deletedValues.sort() # for reproducability only
                r.append(delta.Delete(shared, deletedValues))

        return delta.ModifyOp(dn=self.dn, modifications=r)

    def bind(self, password):
        return defer.maybeDeferred(self._bind, password)

    def _bind(self, password):
        for digest in self.get('userPassword', ()):
            if digest.startswith('{SSHA}'):
                raw = base64.decodestring(digest[len('{SSHA}'):])
                salt = raw[20:]
                got = sshaDigest(password, salt)
                if got == digest:
                    return self
        raise ldaperrors.LDAPInvalidCredentials

    def hasMember(self, dn):
        for memberDN in self.get('member', []):
            if memberDN == dn:
                return True
        return False

    def __hash__(self):
        return hash(self.dn)
Beispiel #53
0
class HTTPClientFactory(protocol.ClientFactory):
    """Download a given URL.

    @type deferred: Deferred
    @ivar deferred: A Deferred that will fire when the content has
          been retrieved. Once this is fired, the ivars `status', `version',
          and `message' will be set.

    @type status: str
    @ivar status: The status of the response.

    @type version: str
    @ivar version: The version of the response.

    @type message: str
    @ivar message: The text message returned with the status.

    @type response_headers: dict
    @ivar response_headers: The headers that were specified in the
          response from the server.
    """

    protocol = HTTPPageGetter

    url = None
    scheme = None
    host = ''
    port = None
    path = None

    def __init__(self, url, method='GET', postdata=None, headers=None,
                 agent="Twisted PageGetter", timeout=0, cookies=None,
                 followRedirect=1, proxy=None):
        self.protocol.followRedirect = followRedirect
        self.timeout = timeout
        self.agent = agent
        self.proxy = proxy

        if cookies is None:
            cookies = {}
        self.cookies = cookies
        if headers is not None:
            self.headers = InsensitiveDict(headers)
        else:
            self.headers = InsensitiveDict()
        if postdata is not None:
            self.headers.setdefault('Content-Length', len(postdata))
            # just in case a broken http/1.1 decides to keep connection alive
            self.headers.setdefault("connection", "close")
        self.postdata = postdata
        self.method = method

        self.setURL(url)

        self.waiting = 1
        self.deferred = defer.Deferred()
        self.response_headers = None

    def __repr__(self):
        return "<%s: %s>" % (self.__class__.__name__, self.url)
    
    def setURL(self, url):
        self.url = url
        scheme, host, port, path = _parse(url)
        if scheme and host:
            self.scheme = scheme
            self.host = host
            self.port = port
        if self.proxy:
            self.path = "%s://%s:%s%s" % (self.scheme,  
                                          self.host,  
                                          self.port,  
                                          path)
        else:
            self.path = path

    def buildProtocol(self, addr):
        p = protocol.ClientFactory.buildProtocol(self, addr)
        if self.timeout:
            timeoutCall = reactor.callLater(self.timeout, p.timeout)
            self.deferred.addBoth(self._cancelTimeout, timeoutCall)
        return p

    def _cancelTimeout(self, result, timeoutCall):
        if timeoutCall.active():
            timeoutCall.cancel()
        return result

    def gotHeaders(self, headers):
        self.response_headers = headers
        if headers.has_key('set-cookie'):
            for cookie in headers['set-cookie']:
                cookparts = cookie.split(';')
                cook = cookparts[0]
                cook.lstrip()
                k, v = cook.split('=', 1)
                self.cookies[k.lstrip()] = v.lstrip()

    def gotStatus(self, version, status, message):
        self.version, self.status, self.message = version, status, message

    def page(self, page):
        if self.waiting:
            self.waiting = 0
            self.deferred.callback(page)

    def noPage(self, reason):
        if self.waiting:
            self.waiting = 0
            self.deferred.errback(reason)

    def clientConnectionFailed(self, _, reason):
        if self.waiting:
            self.waiting = 0
            self.deferred.errback(reason)
Beispiel #54
0
class IRCBot(irc.IRCClient):
    sasl_buffer = ""
    sasl_result = None
    sasl_login = None

    def __init__(self, factory, plugin):
        self.factory     = factory
        self.nickname    = plugin.nickname.encode('ascii')
        self.realname    = plugin.realname.encode('ascii')
        self.username    = plugin.ident.encode('ascii')
        self.ns_username = plugin.username
        self.ns_password = plugin.password
        self.password    = plugin.server_password.encode('ascii')
        self.channel     = plugin.channel.encode('ascii')
        self.console     = plugin.console
        self.irc_message = plugin.irc_message

        self.users       = InsensitiveDict()
        self.cap_requests = set()

    def register(self, nickname, hostname="foo", servername="bar"):
        self.sendLine("CAP LS")
        return irc.IRCClient.register(self, nickname, hostname, servername)

    def _parse_cap(self, cap):
        mod = ''
        while cap[0] in "-~=":
            mod, cap = mod + cap[0], cap[1:]
        if '/' in cap:
            vendor, cap = cap.split('/', 1)
        else:
            vendor = None
        return (cap, mod, vendor)

    def request_cap(self, *caps):
        self.cap_requests |= set(caps)
        self.sendLine("CAP REQ :{0}".format(' '.join(caps)))

    @defer.inlineCallbacks
    def end_cap(self):
        if self.sasl_result:
            yield self.sasl_result
        self.sendLine("CAP END")

    def irc_CAP(self, prefix, params):
        self.supports_cap = True
        identifier, subcommand, args = params
        args = args.split(' ')
        if subcommand == "LS":
            self.sasl_start(args)
            if not self.cap_requests:
                self.sendLine("CAP END")
        elif subcommand == "ACK":
            ack = []
            for cap in args:
                if not cap:
                    continue
                cap, mod, vendor = self._parse_cap(cap)
                if '-' in mod:
                    if cap in self.capabilities:
                        del self.capabilities[cap]
                    continue
                self.cap_requests.remove(cap)
                if cap == 'sasl':
                    self.sasl_next()
            if ack:
                self.sendLine("CAP ACK :{0}".format(' '.join(ack)))
            if not self.cap_requests:
                self.end_cap()
        elif subcommand == "NAK":
            # this implementation is probably not compliant but it will have to do for now
            for cap in args:
                self.cap_requests.remove(cap)
            if not self.cap_requests:
                self.end_cap()

    def signedOn(self):
        if ISSLTransport.providedBy(self.transport):
            cert = self.transport.getPeerCertificate()
            fp = cert.digest("sha1")
            verified = "verified" if self.factory.parent.server_fingerprint else "unverified"
            self.console("irc: connected securely. server fingerprint: {0} ({1})".format(fp, verified))
        else:
            self.console("irc: connected")
        
        if self.ns_username and self.ns_password and not self.sasl_login:
            self.msg('NickServ', 'IDENTIFY {0} {1}'.format(self.ns_username, self.ns_password))
        
        self.join(self.channel)

    def irc_JOIN(self, prefix, params):
        nick = prefix.split('!')[0]
        channel = params[-1]
        if nick == self.nickname:
            self.joined(channel)
        else:
            self.userJoined(prefix, channel)

    def joined(self, channel):
        self.console('irc: joined channel')
        self.factory.client = self
        def who(a):
            self.sendLine("WHO " + channel)
        self.factory.parent.repeating_task(who, 30, now=True)
    
    def isupport(self, args):
        self.compute_prefix_names()
        
    def compute_prefix_names(self):
        KNOWN_NAMES = {"o": "op", "h": "halfop", "v": "voice"}
        prefixdata = self.supported.getFeature("PREFIX", {"o": ("@", 0), "v": ("+", 1)}).items()
        op_priority = ([priority for mode, (prefix, priority) in prefixdata if mode == "o"] + [None])[0]
        self.prefixes, self.statuses, self.priority = {}, {}, {}

        for mode, (prefix, priority) in prefixdata:
            name = "?"
            if mode in KNOWN_NAMES:
                name = KNOWN_NAMES[mode]
            elif priority == 0:
                if op_priority == 2:
                    name = "owner"
                else:
                    name = "admin"
            else:
                name = "+" + mode
            self.prefixes[mode] = prefix
            self.statuses[prefix] = name
            self.priority[name] = priority
            self.priority[mode] = priority
            self.priority[prefix] = priority

    def parse_prefixes(self, user, nick, prefixes=''):
        status = []
        prefixdata = self.supported.getFeature("PREFIX", {"o": ("@", 0), "v": ("+", 1)}).items()
        for mode, (prefix, priority) in prefixdata:
            if prefix in prefixes + nick:
                nick = nick.replace(prefix, '')
                status.append((prefix, priority))
        if nick == self.nickname:
            return
        user.status = ''.join(t[0] for t in sorted(status, key=lambda t: t[1]))
    
    def irc_RPL_WHOREPLY(self, prefix, params):
        _, channel, username, host, server, nick, status, hg = params
        if nick == self.nickname:
            return
        hops, gecos = hg.split(' ', 1)
        user = IRCUser(self, nick)
        user.username = username
        user.hostname = host
        user.oper = '*' in status
        user.away = status[0] == 'G'
        self.users[nick] = user
        self.parse_prefixes(user, nick, status[1:].replace('*', ''))
    
    def modeChanged(self, user, channel, _set, modes, args):
        args = list(args)
        if channel.lower() != self.channel.lower():
            return
        for m, arg in zip(modes, args):
            if m in self.prefixes and arg != self.nickname:
                u = self.users.get(arg, None)
                if u:
                    u.status = u.status.replace(self.prefixes[m], '')
                    if _set:
                        u.status = ''.join(sorted(list(u.status + self.prefixes[m]),
                                                  key=lambda k: self.priority[k]))

    def has_status(self, nick, status):
        if status != 0 and not status:
            return True
        if status not in self.priority:
            return False
        priority = self.priority[status]
        u = self.users.get(nick, None)
        return u and (u.priority is not None) and u.priority <= priority
    
    def userJoined(self, user, channel):
        nick = user.split('!')[0]
        user = IRCUser(self, nick)
        self.users[nick] = user
    
    def userRenamed(self, oldname, newname):
        if oldname not in self.users:
            return
        u = self.users[oldname]
        u.nick = newname
        self.users[newname] = u
        del self.users[oldname]
    
    def userLeft(self, user, channel):
        if user not in self.users:
            return
        del self.users[user]
    
    def userKicked(self, kickee, channel, kicker, message):
        if kickee not in self.users:
            return
        del self.users[kickee]
    
    def userQuit(self, user, quitMessage):
        if user not in self.users:
            return
        del self.users[user]

    def privmsg(self, user, channel, msg):
        if channel != self.channel:
            return
        if '!' not in user:
            return
        nick = user.split('!')[0]
        p = self.factory.parent
        
        if not self.has_status(nick, p.irc_chat_status):
            return

        if p.irc_players_enabled and msg.lower() == p.irc_command_prefix + "players":
            self.say(self.channel, p.irc_players_format.format(players=', '.join(p.players)))

        elif p.irc_command_prefix and msg.startswith(p.irc_command_prefix) and p.irc_command_status and self.has_status(nick, p.irc_command_status):
            argv = msg[len(p.irc_command_prefix):].split(' ')
            command = argv[0]
            if command.startswith('~'):
                if p.irc_command_mark2 and (command.lower() in p.irc_command_allow.lower().split(',') or p.irc_command_allow == '*'):
                    p.dispatch(Hook(line=' '.join(argv)))
            else:
                if command.lower() in p.irc_command_allow.lower().split(',') or p.irc_command_allow == '*':
                    p.send(' '.join(argv))

        else:
            p.irc_message(nick, msg)

    def irc_AUTHENTICATE(self, prefix, params):
        self.sasl_continue(params[0])

    def sasl_send(self, data):
        while data and len(data) >= 400:
            en, data = data[:400].encode('base64').replace('\n', ''), data[400:]
            self.sendLine("AUTHENTICATE " + en)
        if data:
            self.sendLine("AUTHENTICATE " + data.encode('base64').replace('\n', ''))
        else:
            self.sendLine("AUTHENTICATE +")

    def sasl_start(self, cap_list):
        if 'sasl' not in cap_list:
            print cap_list
            return
        self.request_cap('sasl')
        self.sasl_result = defer.Deferred()
        self.sasl_mechanisms = list(SASL_MECHANISMS)

    def sasl_next(self):
        mech = None
        while not mech or not mech.is_valid():
            if not self.sasl_mechanisms:
                return False
            self.sasl_auth = mech = self.sasl_mechanisms.pop(0)(self.ns_username, self.ns_password)
        self.sendLine("AUTHENTICATE " + self.sasl_auth.name)
        return True

    def sasl_continue(self, data):
        if data == '+':
            data = ''
        else:
            data = data.decode('base64')
        if len(data) == 400:
            self.sasl_buffer += data
        else:
            response = self.sasl_auth.respond(self.sasl_buffer + data)
            if response is False:  # abort
                self.sendLine("AUTHENTICATE *")
            else:
                self.sasl_send(response)
            self.sasl_buffer = ""

    def sasl_finish(self):
        if self.sasl_result:
            self.sasl_result.callback(True)
            self.sasl_result = None

    def sasl_failed(self, whine=True):
        if self.sasl_login is False:
            return
        if self.sasl_next():
            return
        self.sasl_login = False
        self.sendLine("AUTHENTICATE *")
        self.sasl_finish()
        if whine:
            self.console("irc: failed to log in.")

    def irc_904(self, prefix, params):
        print params
        self.sasl_failed()

    def irc_905(self, prefix, params):
        print params
        self.sasl_failed()

    def irc_906(self, prefix, params):
        self.sasl_failed(False)

    def irc_907(self, prefix, params):
        self.sasl_failed(False)

    def irc_900(self, prefix, params):
        self.sasl_login = params[2]
        self.console("irc: logged in as '{0}' (using {1})".format(self.sasl_login, self.sasl_auth.name))

    def irc_903(self, prefix, params):
        self.sasl_finish()

    def alterCollidedNick(self, nickname):
        return nickname + '_'

    def irc_relay(self, message):
        self.say(self.channel, message.encode('utf8'))
Beispiel #55
0
class Element(Node):

    preserveCase = 0
    caseInsensitive = 1
    nsprefixes = None
    namespace = ''

    def __init__(self, tagName, attributes=None, parentNode=None,
                        filename=None, markpos=None,
                        caseInsensitive=1, preserveCase=0,
                 namespace=''):
        Node.__init__(self, parentNode)
        self.preserveCase = preserveCase or not caseInsensitive
        self.caseInsensitive = caseInsensitive
        if not preserveCase:
            tagName = tagName.lower()
        if attributes is None:
            self.attributes = {}
        else:
            self.attributes = attributes
            for k, v in self.attributes.items():
                self.attributes[k] = unescape(v)

        if caseInsensitive:
            self.attributes = InsensitiveDict(self.attributes, 
                                              preserve=preserveCase)

        self.endTagName = self.nodeName = self.tagName = tagName
        self._filename = filename
        self._markpos = markpos
        self.namespace = namespace

    def addPrefixes(self, pfxs):
        if self.nsprefixes is None:
            self.nsprefixes = pfxs
        else:
            self.nsprefixes.update(pfxs)

    def endTag(self, endTagName):
        if not self.preserveCase:
            endTagName = endTagName.lower()
        self.endTagName = endTagName

    def isEqualToElement(self, n):
        if self.caseInsensitive:
            return (self.attributes == n.attributes) and (self.nodeName.lower() == n.nodeName.lower())
        return (self.attributes == n.attributes) and (self.nodeName == n.nodeName)

    def cloneNode(self, deep=0, parent=None):
        clone = Element(
            self.tagName, parentNode=parent, namespace=self.namespace,
            preserveCase=self.preserveCase, caseInsensitive=self.caseInsensitive)
        clone.attributes.update(self.attributes)
        if deep:
            clone.childNodes = [child.cloneNode(1, clone) for child in self.childNodes]
        else:
            clone.childNodes = []
        return clone

    def getElementsByTagName(self, name):
        if self.caseInsensitive:
            return getElementsByTagNameNoCase(self, name)
        return getElementsByTagName(self, name)

    def hasAttributes(self):
        return 1

    def getAttribute(self, name, default=None):
        return self.attributes.get(name, default)

    def getAttributeNS(self, ns, name, default=None):
        nsk = (ns, name)
        if self.attributes.has_key(nsk):
            return self.attributes[nsk]
        if ns == self.namespace:
            return self.attributes.get(name, default)
        return default

    def getAttributeNode(self, name):
        return _Attr(self.getAttribute(name), self)

    def setAttribute(self, name, attr):
        self.attributes[name] = attr

    def removeAttribute(self, name):
        if name in self.attributes:
            del self.attributes[name]

    def removeAttribute_has_key(self, name):
        if self.attributes.has_key(name):
            del self.attributes[name]

    def hasAttribute(self, name):
        return name in self.attributes

    def hasAttribute_has_key(self, name):
        return self.attributes.has_key(name)

    if dictsAreNotSequences:
        hasAttribute = hasAttribute_has_key
        removeAttribute = removeAttribute_has_key

    def writexml(self, stream, indent='', addindent='', newl='', strip=0, nsprefixes={}, namespace=''):
        # write beginning
        ALLOWSINGLETON = ('img', 'br', 'hr', 'base', 'meta', 'link', 'param',
                          'area', 'input', 'col', 'basefont', 'isindex',
                          'frame')
        BLOCKELEMENTS = ('html', 'head', 'body', 'noscript', 'ins', 'del',
                         'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'script',
                         'ul', 'ol', 'dl', 'pre', 'hr', 'blockquote',
                         'address', 'p', 'div', 'fieldset', 'table', 'tr',
                         'form', 'object', 'fieldset', 'applet', 'map')
        FORMATNICELY = ('tr', 'ul', 'ol', 'head')

        # this should never be necessary unless people start
        # changing .tagName on the fly(?)
        if not self.preserveCase:
            self.endTagName = self.tagName
        w = stream.write
        if self.nsprefixes:
            newprefixes = self.nsprefixes.copy()
            for ns in nsprefixes.keys():
                del newprefixes[ns]
        else:
             newprefixes = {}

        begin = ['<']
        if self.tagName in BLOCKELEMENTS:
            begin = [newl, indent] + begin
        bext = begin.extend
        writeattr = lambda _atr, _val: bext((' ', _atr, '="', escape(_val), '"'))
        if namespace != self.namespace and self.namespace:
            if nsprefixes.has_key(self.namespace):
                prefix = nsprefixes[self.namespace]
                bext(prefix+':'+self.tagName)
            else:
                bext(self.tagName)
                writeattr("xmlns", self.namespace)
        else:
            bext(self.tagName)
        j = ''.join
        for attr, val in self.attributes.iteritems():
            if isinstance(attr, tuple):
                ns, key = attr
                if nsprefixes.has_key(ns):
                    prefix = nsprefixes[ns]
                else:
                    prefix = genprefix()
                    newprefixes[ns] = prefix
                assert val is not None
                writeattr(prefix+':'+key,val)
            else:
                assert val is not None
                writeattr(attr, val)
        if newprefixes:
            for ns, prefix in newprefixes.iteritems():
                if prefix:
                    writeattr('xmlns:'+prefix, ns)
            newprefixes.update(nsprefixes)
            downprefixes = newprefixes
        else:
            downprefixes = nsprefixes
        w(j(begin))
        if self.childNodes:
            w(">")
            newindent = indent + addindent
            for child in self.childNodes:
                if self.tagName in BLOCKELEMENTS and \
                   self.tagName in FORMATNICELY:
                    w(j((newl, newindent)))
                child.writexml(stream, newindent, addindent, newl, strip, downprefixes, self.namespace)
            if self.tagName in BLOCKELEMENTS:
                w(j((newl, indent)))
            w(j(("</", self.endTagName, '>')))
            
        elif self.tagName.lower() not in ALLOWSINGLETON:
            w(j(('></', self.endTagName, '>')))
        else:
            w(" />")

    def __repr__(self):
        rep = "Element(%s" % repr(self.nodeName)
        if self.attributes:
            rep += ", attributes=%r" % (self.attributes,)
        if self._filename:
            rep += ", filename=%r" % (self._filename,)
        if self._markpos:
            rep += ", markpos=%r" % (self._markpos,)
        return rep + ')'

    def __str__(self):
        rep = "<" + self.nodeName
        if self._filename or self._markpos:
            rep += " ("
        if self._filename:
            rep += repr(self._filename)
        if self._markpos:
            rep += " line %s column %s" % self._markpos
        if self._filename or self._markpos:
            rep += ")"
        for item in self.attributes.items():
            rep += " %s=%r" % item
        if self.hasChildNodes():
            rep += " >...</%s>" % self.nodeName
        else:
            rep += " />"
        return rep
Beispiel #56
0
class HTTPClientFactory(protocol.ClientFactory):
    """Download a given URL.

    @type deferred: Deferred
    @ivar deferred: A Deferred that will fire when the content has
          been retrieved. Once this is fired, the ivars `status', `version',
          and `message' will be set.

    @type status: str
    @ivar status: The status of the response.

    @type version: str
    @ivar version: The version of the response.

    @type message: str
    @ivar message: The text message returned with the status.

    @type response_headers: dict
    @ivar response_headers: The headers that were specified in the
          response from the server.

    @type method: str
    @ivar method: The HTTP method to use in the request.  This should be one of
        OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, or CONNECT (case
        matters).  Other values may be specified if the server being contacted
        supports them.

    @type redirectLimit: int
    @ivar redirectLimit: The maximum number of HTTP redirects that can occur
          before it is assumed that the redirection is endless.

    @type afterFoundGet: C{bool}
    @ivar afterFoundGet: Deviate from the HTTP 1.1 RFC by handling redirects
        the same way as most web browsers; if the request method is POST and a
        302 status is encountered, the redirect is followed with a GET method

    @type _redirectCount: int
    @ivar _redirectCount: The current number of HTTP redirects encountered.
    """

    protocol = HTTPPageGetter

    url = None
    scheme = None
    host = ''
    port = None
    path = None

    def __init__(self,
                 url,
                 method='GET',
                 postdata=None,
                 headers=None,
                 agent="Twisted PageGetter",
                 timeout=0,
                 cookies=None,
                 followRedirect=True,
                 redirectLimit=20,
                 afterFoundGet=False):
        self.followRedirect = followRedirect
        self.redirectLimit = redirectLimit
        self._redirectCount = 0
        self.timeout = timeout
        self.agent = agent
        self.afterFoundGet = afterFoundGet
        if cookies is None:
            cookies = {}
        self.cookies = cookies
        if headers is not None:
            self.headers = InsensitiveDict(headers)
        else:
            self.headers = InsensitiveDict()
        if postdata is not None:
            self.headers.setdefault('Content-Length', len(postdata))
            # just in case a broken http/1.1 decides to keep connection alive
            self.headers.setdefault("connection", "close")
        self.postdata = postdata
        self.method = method

        self.setURL(url)

        self.waiting = 1
        self.deferred = defer.Deferred()
        self.response_headers = None

    def __repr__(self):
        return "<%s: %s>" % (self.__class__.__name__, self.url)

    def setURL(self, url):
        self.url = url
        scheme, host, port, path = _parse(url)
        if scheme and host:
            self.scheme = scheme
            self.host = host
            self.port = port
        self.path = path

    def buildProtocol(self, addr):
        p = protocol.ClientFactory.buildProtocol(self, addr)
        p.followRedirect = self.followRedirect
        p.afterFoundGet = self.afterFoundGet
        if self.timeout:
            timeoutCall = reactor.callLater(self.timeout, p.timeout)
            self.deferred.addBoth(self._cancelTimeout, timeoutCall)
        return p

    def _cancelTimeout(self, result, timeoutCall):
        if timeoutCall.active():
            timeoutCall.cancel()
        return result

    def gotHeaders(self, headers):
        self.response_headers = headers
        if headers.has_key('set-cookie'):
            for cookie in headers['set-cookie']:
                cookparts = cookie.split(';')
                cook = cookparts[0]
                cook.lstrip()
                k, v = cook.split('=', 1)
                self.cookies[k.lstrip()] = v.lstrip()

    def gotStatus(self, version, status, message):
        self.version, self.status, self.message = version, status, message

    def page(self, page):
        if self.waiting:
            self.waiting = 0
            self.deferred.callback(page)

    def noPage(self, reason):
        if self.waiting:
            self.waiting = 0
            self.deferred.errback(reason)

    def clientConnectionFailed(self, _, reason):
        if self.waiting:
            self.waiting = 0
            self.deferred.errback(reason)
Beispiel #57
0
    def _render(self, request, avatar):
        """Node-specific request processing.

        @param request: Web server request.
        @type request: Request

        @type avatar: Host

        @returns: nothing (not a C{Deferred} object!).
            But, due to C{inlineCallbacks}, yields the intermediate
            C{Deferred}s.

        @todo: Proper error handling.

        @todo: Properly handle the situation when the passthrough is
               restricted: generate the reply which contains the Error 404.

        @todo: This should be streamlined using super() as soon
               as C{twisted.web.resource.Resource} becomes a new-style class
        """
        assert not in_main_thread()
        # Kind-of-calling the parent, but the parent in this case should
        # return a Deferred as well,... let's not bother with it.
        # DeferredProcessingResource._render(self, request, avatar)

        logger.debug('')
        logger.debug('')
        logger.debug('Avatar %r;'
                         '\tincoming headers %r;'
                         '\tfrom %r',
                     avatar, request.requestHeaders, request.client)

        # We setup the default headers for response even before
        # we start analyzing the incoming message,
        # so that if analyzing fails for some reason, we have the headers
        # and can create a more-or-less proper error reply.
        _requestHeaders = InsensitiveDict(dict(request.requestHeaders
                                                      .getAllRawHeaders()))

        _responseHeaders = InsensitiveDict()
        self.initialize_headers(_responseHeaders)

        message = self.create_message_from_headers(headers=_requestHeaders,
                                                   auth_peer=avatar)

        message.body_receiver = RequestBodyReceiver(message=message,
                                                    request=request)

        # Make sure the body is received, before going further
        dummy_received_data = yield message.body_receiver.on_finish

        assert not in_main_thread()

        if message.direct:
            # If this is the message directed to ourselves,
            # process it and send the response
            logger.debug('')
            logger.debug('> Der Mitteilung Nahert: %r von %s',
                         message, message.src)

            # Process the incoming message
            try:
                self.tr_manager.handle_incoming_message(message)
            except TransactionProcessingException as e:
                # The incoming transaction cannot be processed.

                # TODO: handle error properly, send a error reply maybe
                logger.error('Error (%r) during incoming msg processing: %s',
                             e, e)

            logger.debug('Will send response to %r from %r %s',
                         message, message.src, hash(message.src))
            for k, v_list in _responseHeaders.iteritems():
                request.responseHeaders.setRawHeaders(k, v_list)
            logger.debug('Done with response headers')
        elif self._accept_passthrough_message(message):
            # Non-direct message, and passthrough allowed:
            # wait for the body, then put in the queue.

            logger.debug('Passthrough message %r: body already available',
                         message)
            self.tr_manager.post_message(message)

        else:
            # Passthrough is restricted for this message!
            raise NotImplementedError(u'Failed message {!r}:\n'
                                           u'from: {!r}\n'
                                           u'  to: {!r}'.format(message,
                                                                message.src,
                                                                message.dst))

        # How to check if we still need a message?
        still_need_checker = lambda: self.connection_alive

        # No matter if we are processing the message or passing it through,
        # we must send a response somehow.

        # If this is the message to us, we'd prefer a response to reply it;
        # but if this is a passthrough message, it will go to a different peer.
        prefer_msg_uuid = message.uuid if message.direct else None
        try:
            # Let's (asynchronously) wait for the response message here.
            resp_msg = self.__response_msg \
                     = yield self.tr_manager.wait_for_message_for_peer(
                                 inh=message.src,
                                 prefer_msg_uuid=prefer_msg_uuid,
                                 still_wait_checker=still_need_checker)
        except internet_error.ConnectionClosed as e:
            logger.warning('Stopped to wait for a message due to %r', e)
            self._handle_connection_close(Failure(e))
        except Exception as e:
            logger.exception('Stopped to wait for a message due to %r', e)
            self._handle_connection_close(Failure(e))
        else:
            # Since now and till the end of transfer we store the message
            # in self.__response_msg.

            assert not in_main_thread()

            if resp_msg is None:
                # The connection died already, while waiting for the message.
                assert not self.connection_alive

            else:
                # Got the message, send it back
                assert isinstance(resp_msg, AbstractMessage), repr(resp_msg)
                self.__send_http_response(message.src, request, resp_msg)
Beispiel #58
0
    def _render(self, request, avatar):
        """Node-specific request processing.

        @param request: Web server request.
        @type request: Request

        @type avatar: Host

        @returns: nothing (not a C{Deferred} object!).
            But, due to C{inlineCallbacks}, yields the intermediate
            C{Deferred}s.

        @todo: Proper error handling.

        @todo: Properly handle the situation when the passthrough is
               restricted: generate the reply which contains the Error 404.

        @todo: This should be streamlined using super() as soon
               as C{twisted.web.resource.Resource} becomes a new-style class
        """
        assert not in_main_thread()
        # Kind-of-calling the parent, but the parent in this case should
        # return a Deferred as well,... let's not bother with it.
        # DeferredProcessingResource._render(self, request, avatar)

        logger.debug('')
        logger.debug('')
        logger.debug('Avatar %r;'
                     '\tincoming headers %r;'
                     '\tfrom %r', avatar, request.requestHeaders,
                     request.client)

        # We setup the default headers for response even before
        # we start analyzing the incoming message,
        # so that if analyzing fails for some reason, we have the headers
        # and can create a more-or-less proper error reply.
        _requestHeaders = InsensitiveDict(
            dict(request.requestHeaders.getAllRawHeaders()))

        _responseHeaders = InsensitiveDict()
        self.initialize_headers(_responseHeaders)

        message = self.create_message_from_headers(headers=_requestHeaders,
                                                   auth_peer=avatar)

        message.body_receiver = RequestBodyReceiver(message=message,
                                                    request=request)

        # Make sure the body is received, before going further
        dummy_received_data = yield message.body_receiver.on_finish

        assert not in_main_thread()

        if message.direct:
            # If this is the message directed to ourselves,
            # process it and send the response
            logger.debug('')
            logger.debug('> Der Mitteilung Nahert: %r von %s', message,
                         message.src)

            # Process the incoming message
            try:
                self.tr_manager.handle_incoming_message(message)
            except TransactionProcessingException as e:
                # The incoming transaction cannot be processed.

                # TODO: handle error properly, send a error reply maybe
                logger.error('Error (%r) during incoming msg processing: %s',
                             e, e)

            logger.debug('Will send response to %r from %r %s', message,
                         message.src, hash(message.src))
            for k, v_list in _responseHeaders.iteritems():
                request.responseHeaders.setRawHeaders(k, v_list)
            logger.debug('Done with response headers')
        elif self._accept_passthrough_message(message):
            # Non-direct message, and passthrough allowed:
            # wait for the body, then put in the queue.

            logger.debug('Passthrough message %r: body already available',
                         message)
            self.tr_manager.post_message(message)

        else:
            # Passthrough is restricted for this message!
            raise NotImplementedError(u'Failed message {!r}:\n'
                                      u'from: {!r}\n'
                                      u'  to: {!r}'.format(
                                          message, message.src, message.dst))

        # How to check if we still need a message?
        still_need_checker = lambda: self.connection_alive

        # No matter if we are processing the message or passing it through,
        # we must send a response somehow.

        # If this is the message to us, we'd prefer a response to reply it;
        # but if this is a passthrough message, it will go to a different peer.
        prefer_msg_uuid = message.uuid if message.direct else None
        try:
            # Let's (asynchronously) wait for the response message here.
            resp_msg = self.__response_msg \
                     = yield self.tr_manager.wait_for_message_for_peer(
                                 inh=message.src,
                                 prefer_msg_uuid=prefer_msg_uuid,
                                 still_wait_checker=still_need_checker)
        except internet_error.ConnectionClosed as e:
            logger.warning('Stopped to wait for a message due to %r', e)
            self._handle_connection_close(Failure(e))
        except Exception as e:
            logger.exception('Stopped to wait for a message due to %r', e)
            self._handle_connection_close(Failure(e))
        else:
            # Since now and till the end of transfer we store the message
            # in self.__response_msg.

            assert not in_main_thread()

            if resp_msg is None:
                # The connection died already, while waiting for the message.
                assert not self.connection_alive

            else:
                # Got the message, send it back
                assert isinstance(resp_msg, AbstractMessage), repr(resp_msg)
                self.__send_http_response(message.src, request, resp_msg)