This file is indexed.

/usr/lib/python2.7/dist-packages/txwinrm/SessionManager.py is in python-txwinrm 1.1.28-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
203
204
205
##############################################################################
#
# Copyright (C) Zenoss, Inc. 2016, all rights reserved.
#
# This content is made available according to terms specified in
# License.zenoss under the directory where your Zenoss product is installed.
#
##############################################################################

"""txsessionmgr - Python module for a single persistent connection to a device
for multiple clients.

Useful for situations when multiple connections to a device can be handled
with one connection through a single login, e.g. txciscoapic, txwinrm

The global SESSION_MANAGER is instantiated one time and is used to manage
all sessions

Session should be subclassed and implemented to login/logout, send requests,
and handle responses

A Client should always have a key property.  This will be unique to the types
of transactions/requests being made through a single Session

"""

from twisted.internet.defer import inlineCallbacks, returnValue, succeed


class Session(object):
    """
    Session handler for connection to a device.

    deferred_init will kick off a deferred login to a device from the first
    client that needs the connection.  Subsequent clients will use the data
    returned from the first login.

    The Session class is responsible for implementing the login/logout methods
    """
    def __init__(self):
        # Used to keep track of clients using session
        self._clients = set()

        # The currently valid token.  This can be anything that the client
        # needs to know the connection is alive
        self._token = None

        # Deferred waiting for login result.
        self._login_d = None

        # Error from last login if applicable.
        self._login_error = None

        # Deferred sending a refresh/keep-alive signal/request
        self._refresh_d = None

    @inlineCallbacks
    def deferred_login(self, client):
        """Return Deferred token

        :param client: Client initiating a connection
        :client: ZenPack specific client
        :rtype: Deferred
        :return: Returns ZenPack unique token to be used for a session.
        """
        self._clients.add(client)
        if self._token:
            returnValue(self._token)

        # No one already waiting for a token. Login to get a new one.
        if not self._login_d or self._login_d.called:
            self._login_d = self._deferred_login(client)

            try:
                self._token = yield self._login_d
            except Exception as e:
                self._login_error = e
                raise

        # At least one other client is already waiting for a token, and
        # the login to get it is already in progress. Wait for that
        # login to finish, then return its token.
        else:
            yield self._login_d
            if self._login_error:
                raise self._login_error

        returnValue(self._token)

    @inlineCallbacks
    def deferred_logout(self, client):
        """Return Deferred None.

        Calls session._deferred_logout() only if all other clients using the same
        session have also called deferred_logout.

        """
        if len(self._clients) <= 1:
            if self._token:
                try:
                    yield self._deferred_logout()
                except Exception:
                    pass

            self._token = None

        if client in self._clients:
            self._clients.remove(client)
        returnValue(None)

    @inlineCallbacks
    def _deferred_login(self, client):
        '''login method

        Performs the ZenPack specific login to a device.  This will only be called
        from the first client to fire off the deferred.  All other clients will
        use the _token returned from this method

        :param client: Client initiating a connection
        :type client: ZenPack specific client
        :rtype: Deferred
        :return: Returns a Deferred which is logs into the device.
        '''
        returnValue(None)

    @inlineCallbacks
    def _deferred_logout(self):
        '''logout method

        Performs the ZenPack specific logout from a device.  This will only be called
        by the last client to logout of the session.

        :rtype: Deferred
        :return: Returns a Deferred which logs out of the device
        '''
        returnValue(None)


class SessionManager(object):
    '''
    Class to manage open sessions to devices.
    '''
    def __init__(self):
        # Used to keep track of sessions
        self._sessions = {}

    def get_connection(self, key):
        '''Return the session for a given key
        '''
        if key is None:
            raise Exception('Client key cannot be empty')
        return self._sessions.get(key, None)

    def remove_connection(self, key):
        session = self.get_connection(key)
        if session:
            self._sessions.pop(session)

    @inlineCallbacks
    def init_connection(self, client, session_class=Session):
        '''Initialize connection to device.
        If a session is already started return it.
        Else kick off deferred to initiate session

        The client must contain a key for session storage

        :param client: Client initiating connection
        :client: ZenPack defined client.
        '''
        if not hasattr(client, 'key'):
            raise Exception('Client must contain a key field')

        session = self.get_connection(client.key)
        if session:
            if session._token:
                if client not in session._clients:
                    session._clients.add(client)
                returnValue(session._token)

        if session is None:
            session = session_class()
            self._sessions[client.key] = session

        token = yield session.deferred_login(client)
        returnValue(token)

    @inlineCallbacks
    def close_connection(self, client):
        '''Kick off a session's logout
        If there are no more clients using a session, remove it

        :param client:  Client closing connection
        :client: ZenPack defined class
        '''
        session = self.get_connection(client.key)
        if not session:
            returnValue(None)
        yield session.deferred_logout(client)
        if not session._clients:
            # no more clients so we don't need to keep the session
            self._sessions.pop(client.key)
        returnValue(None)


SESSION_MANAGER = SessionManager()