This file is indexed.

/usr/lib/python2.7/dist-packages/shinken/pyro_wrapper.py is in shinken-common 1.4-2.

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
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
#!/usr/bin/env python

# -*- coding: utf-8 -*-

# Copyright (C) 2009-2012:
#     Gabes Jean, naparuba@gmail.com
#     Gerhard Lausser, Gerhard.Lausser@consol.de
#     Gregory Starck, g.starck@gmail.com
#     Hartmut Goebel, h.goebel@goebel-consult.de
#
# This file is part of Shinken.
#
# Shinken is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Shinken 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with Shinken.  If not, see <http://www.gnu.org/licenses/>.

import select
import errno
import time
import socket
from log import logger

# Try to import Pyro (3 or 4.1) and if not, Pyro4 (4.2 and 4.3)
try:
    import Pyro
    import Pyro.core
except ImportError:  # ok, no Pyro3, maybe 4
    import Pyro4 as Pyro


""" This class is a wrapper for managing Pyro 3 and 4 version """


class InvalidWorkDir(Exception):
    pass


class PortNotFree(Exception):
    pass

PYRO_VERSION = 'UNKNOWN'


# Try to see if we are Python 3 or 4
try:
    Pyro.core.ObjBase
    # Some one already go here, so we are in 4 if None
    if Pyro.core.ObjBase is None:
        raise AttributeError

    PYRO_VERSION = Pyro.constants.VERSION
    Pyro.errors.CommunicationError = Pyro.errors.ProtocolError
    Pyro.errors.TimeoutError = Pyro.errors.ProtocolError


    class Pyro3Daemon(Pyro.core.Daemon):
        pyro_version = 3
        protocol = 'PYROLOC'

        def __init__(self, host, port, use_ssl=False):
            self.port = port
            # Port = 0 means "I don't want pyro"
            if self.port == 0:
                return
            try:
                Pyro.core.initServer()
            except (OSError, IOError), e:  # must be problem with workdir:
                raise InvalidWorkDir(e)
            # Set the protocol as asked (ssl or not)
            if use_ssl:
                prtcol = 'PYROSSL'
            else:
                prtcol = 'PYRO'

            logger.info("Initializing Pyro connection with host:%s port:%s ssl:%s" %
                        (host, port, str(use_ssl)))
            # Now the real start
            try:
                Pyro.core.Daemon.__init__(self, host=host, port=port, prtcol=prtcol, norange=True)
            except OSError, e:
                # must be problem with workdir:
                raise InvalidWorkDir(e)
            except Pyro.errors.DaemonError, e:
                msg = "Error: Sorry, the port %d is not free: %s" % (port, e)
                raise PortNotFree(msg)

        def register(self, obj, name):
            return self.connect(obj, name)

        def unregister(self, obj):
            try:
                self.disconnect(obj)
            except Exception:
                pass

        def get_sockets(self):
            if self.port != 0:
                return self.getServerSockets()
            return []

        def handleRequests(self, s):
            try:
                Pyro.core.Daemon.handleRequests(self)
            # Sometime Pyro send us xml pickling implementation (gnosis) is not available
            # and I don't know why... :(
            except NotImplementedError:
                pass
            # Maybe it's just a protocol error, like someone with a telnet
            # tying to talk with us, bypass this
            except ProtocolError:
                pass
                logger.warning("Someone is talking to me in a strange language!")


    def create_uri(address, port, obj_name, use_ssl):
        if not use_ssl:
            return "PYROLOC://%s:%d/%s" % (address, port, obj_name)
        else:
            return "PYROLOCSSL://%s:%d/%s" % (address, port, obj_name)


    # Timeout way is also changed between 3 and 4
    # it's a method in 3, a property in 4
    def set_timeout(con, timeout):
        con._setTimeout(timeout)


    def getProxy(uri):
        return Pyro.core.getProxyForURI(uri)


    # Shutdown in 3 take True as arg
    def shutdown(con):
        con.shutdown(True)

    PyroClass = Pyro3Daemon


except AttributeError, exp:

    PYRO_VERSION = Pyro.constants.VERSION
    # Ok, in Pyro 4, interface do not need to
    # inherit from ObjBase, just a dummy class is good
    Pyro.core.ObjBase = dict
    Pyro.errors.URIError = Pyro.errors.ProtocolError
    Pyro.core.getProxyForURI = Pyro.core.Proxy
    Pyro.config.HMAC_KEY = "NOTSET"

    old_versions = ["4.1", "4.2", "4.3", "4.4"]

    # Version not supported for now, we have to work on it
    bad_versions = []
    last_known_working_version = "4.14"
    msg_waitall_issue_versions = ["4.1", "4.2", "4.3", "4.4", "4.5", "4.6", "4.7", '4.8',
                                  '4.9', '4.10', '4.11', '4.12', '4.13']

    class Pyro4Daemon(Pyro.core.Daemon):
        pyro_version = 4
        protocol = 'PYRO'

        def __init__(self, host, port, use_ssl=False):
            self.port = port
            # Port = 0 means "I don't want pyro"
            if self.port == 0:
                return

            # Some version with Pyro got problems with the socket.MSG_WAITALL
            # It was "solved" in 4.14. But before this, just delete it
            if PYRO_VERSION in msg_waitall_issue_versions:
                if hasattr(socket, 'MSG_WAITALL'):
                    del socket.MSG_WAITALL

            # Pyro 4 is by default a thread, should do select
            # (I hate threads!)
            # And of course the name changed since 4.5...
            # Since then, we got a better sock reuse, so
            # before 4.5 we must wait 35 s for the port to stop
            # and in >=4.5 we can use REUSE socket :)
            max_try = 35
            if PYRO_VERSION in old_versions:
                Pyro.config.SERVERTYPE = "select"
            elif PYRO_VERSION in bad_versions:
                logger.error("Your pyro version (%s) is not supported. Please install version (%s) "
                             % (PYRO_VERSION, last_known_working_version))
                exit(1)
            else:
                Pyro.config.SERVERTYPE = "multiplex"
                # For Pyro >4.X hash
                if hasattr(Pyro.config, 'SOCK_REUSE'):
                    Pyro.config.SOCK_REUSE = True
                    max_try = 1
            nb_try = 0
            #is_good = False # not used
            # Ok, Pyro4 do not close sockets like it should,
            # so we got TIME_WAIT socket :(
            # so we allow to retry during 35 sec (30 sec is the default
            # timewait for close sockets)
            while nb_try < max_try:
                nb_try += 1
                logger.info("Initializing Pyro connection with host:%s port:%s ssl:%s" %
                            (host, port, str(use_ssl)))
                # And port already use now raise an exception
                try:
                    Pyro.core.Daemon.__init__(self, host=host, port=port)
                    # Ok, we got our daemon, we can exit
                    break
                except socket.error, exp:
                    msg = "Error: Sorry, the port %d is not free: %s" % (port, str(exp))
                    # At 35 (or over), we are very not happy
                    if nb_try >= max_try:
                        raise PortNotFree(msg)
                    logger.error(msg + "but we try another time in 1 sec")
                    time.sleep(1)
                except Exception, e:
                    # must be a problem with pyro workdir:
                    raise InvalidWorkDir(e)

        # Get the server socket but not if disabled
        def get_sockets(self):
            if self.port == 0:
                return []
            if PYRO_VERSION in old_versions:
                return self.sockets()
            else:
                return self.sockets

        def handleRequests(self, s):
            try:
                if PYRO_VERSION in old_versions:
                    Pyro.core.Daemon.handleRequests(self, [s])
                else:
                    Pyro.core.Daemon.events(self, [s])
            # Catch bad protocol attemps, like a telnet connexion
            except ProtocolError:
                pass
                logger.warning("Someone is talking to me in a strange language!")


    def create_uri(address, port, obj_name, use_ssl=False):
        return "PYRO:%s@%s:%d" % (obj_name, address, port)


    def set_timeout(con, timeout):
        con._pyroTimeout = timeout


    def getProxy(uri):
        return Pyro.core.Proxy(uri)


    # Shutdown in 4 do not take arg
    def shutdown(con):
        con.shutdown()
        con.close()

    PyroClass = Pyro4Daemon


class ShinkenPyroDaemon(PyroClass):
    """Class for wrapping select calls for Pyro"""
    locationStr = '__NOTSET__'  # To by pass a bug in Pyro, this should be set in __init__, but
                                # if we try to print an uninitialized object, it's not happy
    objectsById = []            # Same here...

    def get_socks_activity(self, timeout):
        try:
            ins, _, _ = select.select(self.get_sockets(), [], [], timeout)
        except select.error, e:
            errnum, _ = e
            if errnum == errno.EINTR:
                return []
            raise
        return ins

# Common exceptions to be catch
Pyro_exp_pack = (Pyro.errors.ProtocolError, Pyro.errors.URIError,
                 Pyro.errors.CommunicationError,
                 Pyro.errors.DaemonError, Pyro.errors.ConnectionClosedError,
                 Pyro.errors.TimeoutError, Pyro.errors.NamingError)