This file is indexed.

/usr/share/pyshared/pyxmpp/jabberd/componentstream.py is in python-pyxmpp 1.1.2-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
#
# (C) Copyright 2003-2010 Jacek Konieczny <jajcus@jajcus.net>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License Version
# 2.1 as published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
# pylint: disable-msg=W0221, W0201
"""Component (jabber:component:accept) stream handling.

Normative reference:
  - `JEP 114 <http://www.jabber.org/jeps/jep-0114.html>`__
"""

__docformat__="restructuredtext en"

import hashlib

import logging

from pyxmpp.stream import Stream
from pyxmpp.streambase import stanza_factory,HostMismatch
from pyxmpp.xmlextra import common_doc,common_root
from pyxmpp.utils import to_utf8
from pyxmpp.exceptions import StreamError,FatalStreamError,ComponentStreamError,FatalComponentStreamError

class ComponentStream(Stream):
    """Handles jabberd component (jabber:component:accept) connection stream.

    :Ivariables:
        - `server`: server to use.
        - `port`: port number to use.
        - `secret`: authentication secret.
    :Types:
        - `server`: `unicode`
        - `port`: `int`
        - `secret`: `unicode`"""

    def __init__(self, jid, secret, server, port, keepalive = 0, owner = None):
        """Initialize a `ComponentStream` object.

        :Parameters:
            - `jid`: JID of the component.
            - `secret`: authentication secret.
            - `server`: server address.
            - `port`: TCP port number on the server.
            - `keepalive`: keepalive interval. 0 to disable.
            - `owner`: `Client`, `Component` or similar object "owning" this stream.
        """
        Stream.__init__(self, "jabber:component:accept",
                    sasl_mechanisms = [],
                    tls_settings = None,
                    keepalive = keepalive,
                    owner = owner)
        self.server=server
        self.port=port
        self.me=jid
        self.secret=secret
        self.process_all_stanzas=1
        self.__logger=logging.getLogger("pyxmpp.jabberd.ComponentStream")

    def _reset(self):
        """Reset `ComponentStream` object state, making the object ready to
        handle new connections."""
        Stream._reset(self)

    def connect(self,server=None,port=None):
        """Establish a client connection to a server.

        [component only]

        :Parameters:
            - `server`: name or address of the server to use.  If not given
              then use the one specified when creating the object.
            - `port`: port number of the server to use.  If not given then use
              the one specified when creating the object.

        :Types:
            - `server`: `unicode`
            - `port`: `int`"""
        self.lock.acquire()
        try:
            self._connect(server,port)
        finally:
            self.lock.release()

    def _connect(self,server=None,port=None):
        """Same as `ComponentStream.connect` but assume `self.lock` is acquired."""
        if self.me.node or self.me.resource:
            raise Value, "Component JID may have only domain defined"
        if not server:
            server=self.server
        if not port:
            port=self.port
        if not server or not port:
            raise ValueError, "Server or port not given"
        Stream._connect(self,server,port,None,self.me)

    def accept(self,sock):
        """Accept an incoming component connection.

        [server only]

        :Parameters:
            - `sock`: a listening socket."""
        Stream.accept(self,sock,None)

    def stream_start(self,doc):
        """Process <stream:stream> (stream start) tag received from peer.

        Call `Stream.stream_start`, but ignore any `HostMismatch` error.

        :Parameters:
            - `doc`: document created by the parser"""
        try:
            Stream.stream_start(self,doc)
        except HostMismatch:
            pass

    def _post_connect(self):
        """Initialize authentication when the connection is established
        and we are the initiator."""
        if self.initiator:
            self._auth()

    def _compute_handshake(self):
        """Compute the authentication handshake value.

        :return: the computed hash value.
        :returntype: `str`"""
        return hashlib.sha1(to_utf8(self.stream_id)+to_utf8(self.secret)).hexdigest()

    def _auth(self):
        """Authenticate on the server.

        [component only]"""
        if self.authenticated:
            self.__logger.debug("_auth: already authenticated")
            return
        self.__logger.debug("doing handshake...")
        hash_value=self._compute_handshake()
        n=common_root.newTextChild(None,"handshake",hash_value)
        self._write_node(n)
        n.unlinkNode()
        n.freeNode()
        self.__logger.debug("handshake hash sent.")

    def _process_node(self,node):
        """Process first level element of the stream.

        Handle component handshake (authentication) element, and
        treat elements in "jabber:component:accept", "jabber:client"
        and "jabber:server" equally (pass to `self.process_stanza`).
        All other elements are passed to `Stream._process_node`.

        :Parameters:
            - `node`: XML node describing the element
        """
        ns=node.ns()
        if ns:
            ns_uri=node.ns().getContent()
        if (not ns or ns_uri=="jabber:component:accept") and node.name=="handshake":
            if self.initiator and not self.authenticated:
                self.authenticated=1
                self.state_change("authenticated",self.me)
                self._post_auth()
                return
            elif not self.authenticated and node.getContent()==self._compute_handshake():
                self.peer=self.me
                n=common_doc.newChild(None,"handshake",None)
                self._write_node(n)
                n.unlinkNode()
                n.freeNode()
                self.peer_authenticated=1
                self.state_change("authenticated",self.peer)
                self._post_auth()
                return
            else:
                self._send_stream_error("not-authorized")
                raise FatalComponentStreamError,"Hanshake error."

        if ns_uri in ("jabber:component:accept","jabber:client","jabber:server"):
            stanza=stanza_factory(node)
            self.lock.release()
            try:
                self.process_stanza(stanza)
            finally:
                self.lock.acquire()
                stanza.free()
            return
        return Stream._process_node(self,node)

# vi: sts=4 et sw=4