4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / RSCDAdapter.py PY
# A requests adapter for handling RSCD connections to BMC BladeLogic agents.
# It's amazing how much code is required just to prepend an SSL connection with a couple of cleartext characters
# before letting requests use it.

import socket
import httplib
import ssl
import requests

from requests.adapters import HTTPAdapter
from requests.compat import urlparse

class RSCDConnection(httplib.HTTPConnection, object):

    def __init__(self, host, port, timeout=60):
        super(RSCDConnection, self).__init__(host, timeout=timeout)
        self.sock = None
        self.timeout = timeout
        self.host = host
        self.port = port

    def __del__(self):  # base class does not have d'tor
        if self.sock:
            self.sock.close()

    def connect(self):
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(self.timeout)
        sock.connect((self.host, self.port))
        sock.sendall("TLSRPC")
        self.sock = ssl.wrap_socket(sock)


class RSCDConnectionPool(requests.packages.urllib3.connectionpool.HTTPConnectionPool):

    def __init__(self, url, port, timeout=60):
        super(RSCDConnectionPool, self).__init__(url, port, timeout=timeout)
        self.host = urlparse(url).hostname
        self.timeout = timeout

    def _new_conn(self):
        return RSCDConnection(self.host, self.port, self.timeout)


class RSCDAdapter(HTTPAdapter):

    def __init__(self, port=4750, timeout=60, pool_connections=25):
        super(RSCDAdapter, self).__init__()
        self.timeout = timeout
        self.port = port
        self.pools = requests.packages.urllib3._collections.RecentlyUsedContainer(
            pool_connections, dispose_func=lambda p: p.close()
        )
        super(RSCDAdapter, self).__init__()

    def get_connection(self, url, proxies=None):
        proxies = proxies or {}
        proxy = proxies.get(urlparse(url.lower()).scheme)

        if proxy:
           raise ValueError('%s does not support specifying proxies' % self.__class__.__name__)

        with self.pools.lock:
           pool = self.pools.get(url)
           if pool:
               return pool

           pool = RSCDConnectionPool(url, self.port, self.timeout)
           self.pools[url] = pool

        return pool

    def request_url(self, request, proxies):
        return request.path_url

    def close(self):
        self.pools.clear()