def __init__(oSelf,
                 oServerBaseURL,
                 u0zMaxNumberOfConnectionsToServer=zNotProvided,
                 o0SSLContext=None):
        oSelf.__oServerBaseURL = oServerBaseURL
        oSelf.__u0MaxNumberOfConnectionsToServer = fxGetFirstProvidedValue(
            u0zMaxNumberOfConnectionsToServer,
            gu0DefaultMaxNumberOfConnectionsToServer)
        oSelf.__o0SSLContext = o0SSLContext

        oSelf.__oConnectionsPropertyLock = cLock(
            "%s.__oConnectionsPropertyLock" % oSelf.__class__.__name__,
            n0DeadlockTimeoutInSeconds=gnDeadlockTimeoutInSeconds)
        oSelf.__aoConnections = []
        oSelf.__uPendingConnects = 0

        oSelf.__bStopping = False
        oSelf.__oTerminatedPropertyLock = cLock(
            "%s.__oTerminatedEventFiredLock" % oSelf.__class__.__name__,
            n0DeadlockTimeoutInSeconds=gnDeadlockTimeoutInSeconds)
        oSelf.__oTerminatedLock = cLock("%s.__oTerminatedLock" %
                                        oSelf.__class__.__name__,
                                        bLocked=True)

        oSelf.fAddEvents("connect failed", "new connection", "request sent",
                         "response received",
                         "request sent and response received",
                         "connection terminated", "terminated")
Example #2
0
 def __init__(oSelf,
              oPythonSocket,
              o0SecurePythonSocket=None,
              o0SSLContext=None,
              szRemoteHostname=zNotProvided,
              bCreatedLocally=False):
     # The initial python socket is not secure. We can "wrap" the socket with SSL
     # to secure it repeatedly to "tunnel" multiple SSL connections. Each time
     # a new SSL connection is tunneled through the existing connection, a new
     # "wrapped" socket is created that can be used to communicate through this
     # SSL tunnel. We will keep a list of the python sockets corresponding to
     # these tunnels, in order:
     oSelf.__aoPythonSockets = [
         o0 for o0 in [oPythonSocket, o0SecurePythonSocket] if o0
     ]
     # We also keep a list of the SSL contexts for the tunneled secured
     # connections. This list is in the same order but does not have an entry
     # for the first socket, as it is not secure.
     oSelf.__aoSSLContexts = [o0 for o0 in [o0SSLContext] if o0]
     oSelf.__bCreatedLocally = bCreatedLocally
     oSelf.uReadChunkSize = oSelf.uDefaultReadChunkSize
     # We will create a lock that will be released as soon as we detect that the
     # socket is disconnected to implement fbWait()
     oSelf.__oTerminatedLock = cLock("%s.__oTerminatedLock" %
                                     oSelf.__class__.__name__,
                                     bLocked=True)
     # When we detect a disconnect, we need a way to check if this is the first
     # time that we detect it, so we can be sure we release the oConnectedLock
     # only once. This requires exclusive acccess to the "connected" property
     # to prevent race conditions where the lock is freed twice in two threads:
     oSelf.__oConnectedPropertyAccessLock = cLock(
         "%s.__oConnectedPropertyAccessLock" % oSelf.__class__.__name__,
         n0DeadlockTimeoutInSeconds=gnDeadlockTimeoutInSeconds)
     # We will also keep track of the fact that "fStop" of "fTerminate" has been called.
     oSelf.__bStopping = False
     oSelf.__bShouldAllowReading = True
     oSelf.__bShouldAllowWriting = True
     oSelf.txLocalAddress = (
         oSelf.sLocalHostname,
         oSelf.uLocalPort) = oSelf.__oPythonSocket.getsockname()
     oSelf.sLocalAddress = "localhost:%d" % oSelf.uLocalPort
     oSelf.txRemoteAddress = (
         oSelf.sRemoteHostname,
         oSelf.uRemotePort) = oSelf.__oPythonSocket.getpeername()
     if fbIsProvided(szRemoteHostname):
         oSelf.sRemoteHostname = szRemoteHostname
     oSelf.sRemoteAddress = "%s:%d" % (oSelf.sRemoteHostname,
                                       oSelf.uRemotePort)
     oSelf.fAddEvents("bytes read", "bytes written", "shutdown for reading",
                      "shutdown for writing", "shutdown", "terminated")
 def __init__(oSelf, *txArguments, **dxArguments):
     oSelf.__bStopping = False
     # A properties lock is used to make sure different threads can perform
     # multiple read/writes on properties of this instance as a single operation.
     oSelf.__oPropertiesLock = cLock(
         "%s.__oPropertiesLock" % oSelf.__class__.__name__,
         n0DeadlockTimeoutInSeconds=gnDeadlockTimeoutInSeconds)
     oSelf.__oWaitingUntilSomeStateLock = cLock(
         "%s.__oWaitingUntilSomeStateLock" % oSelf.__class__.__name__)
     oSelf.__oTransactionLock = cLock("%s.__oTransactionLock" %
                                      oSelf.__class__.__name__)
     oSelf.__n0TransactionEndTime = None
     super(cTransactionalBufferedTCPIPConnection,
           oSelf).__init__(*txArguments, **dxArguments)
     oSelf.fAddEvents("transaction started", "transaction ended")
Example #4
0
 def __init__(oSelf, fNewConnectionHandler, szHostname = zNotProvided, uzPort = zNotProvided, o0SSLContext = None, n0zSecureTimeoutInSeconds = zNotProvided):
   oSelf.__fNewConnectionHandler = fNewConnectionHandler;
   oSelf.__sHostname = fxGetFirstProvidedValue(szHostname, socket.gethostname());
   oSelf.__uPort = fxGetFirstProvidedValue(uzPort, 443 if o0SSLContext else 80);
   oSelf.__o0SSLContext = o0SSLContext;
   assert o0SSLContext is None or c0SSLException is not None, \
       "Cannot load SSL support";
   oSelf.__n0zSecureTimeoutInSeconds = n0zSecureTimeoutInSeconds;
   
   oSelf.__bStopping = False;
   oSelf.__oTerminatedLock = cLock(
     "%s.__oTerminatedLock" % oSelf.__class__.__name__,
     bLocked = True
   );
   
   oSelf.__oPythonSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0);
   oSelf.__oPythonSocket.settimeout(None);
   oSelf.__oPythonSocket.bind((oSelf.__sHostname, oSelf.__uPort));
   oSelf.__oPythonSocket.listen(1);
   oSelf.__oMainThread = cThread(oSelf.__fMain);
   oSelf.__oMainThread.fStart(bVital = False);
   oSelf.fAddEvents(
     "new connection", # Fired first for both secure and nonsecure connections
     "new nonsecure connection", # Fired for nonsecure connections only.
     "new secure connection", # Fired after SSL negotiation has completed successfully.
     "connection cannot be secured", # Fired if SSL negotiation failed to complete successfully and before timeout.
     "terminated" # Fired when the acceptor stops accepting connections.
   );
Example #5
0
    def __init__(
        oSelf,
        o0zCertificateStore=zNotProvided,
        u0zMaxNumberOfConnectionsToServer=zNotProvided,
        n0zConnectTimeoutInSeconds=zNotProvided,
        n0zSecureTimeoutInSeconds=zNotProvided,
        n0zTransactionTimeoutInSeconds=zNotProvided,
        bAllowUnverifiableCertificates=False,
        bCheckHostname=True,
    ):
        oSelf.__o0CertificateStore = (
            o0zCertificateStore if fbIsProvided(o0zCertificateStore) else
            c0CertificateStore() if c0CertificateStore else None)
        oSelf.__u0zMaxNumberOfConnectionsToServer = fxGetFirstProvidedValue(
            u0zMaxNumberOfConnectionsToServer,
            oSelf.u0zDefaultMaxNumberOfConnectionsToServer)
        # Timeouts can be provided through class default, instance defaults, or method call arguments.
        oSelf.__n0zConnectTimeoutInSeconds = fxzGetFirstProvidedValueIfAny(
            n0zConnectTimeoutInSeconds,
            oSelf.n0zDefaultConnectTimeoutInSeconds)
        oSelf.__n0zSecureTimeoutInSeconds = fxzGetFirstProvidedValueIfAny(
            n0zSecureTimeoutInSeconds, oSelf.n0zDefaultSecureTimeoutInSeconds)
        oSelf.__n0zTransactionTimeoutInSeconds = fxzGetFirstProvidedValueIfAny(
            n0zTransactionTimeoutInSeconds,
            oSelf.n0zDefaultTransactionTimeoutInSeconds)
        oSelf.__bAllowUnverifiableCertificates = bAllowUnverifiableCertificates
        oSelf.__bCheckHostname = bCheckHostname

        oSelf.__oPropertyAccessTransactionLock = cLock(
            "%s.__oPropertyAccessTransactionLock" % oSelf.__class__.__name__,
            n0DeadlockTimeoutInSeconds=gnDeadlockTimeoutInSeconds)
        oSelf.__doConnectionsToServerPool_by_sProtocolHostPort = {}

        oSelf.__bStopping = False
        oSelf.__oTerminatedLock = cLock("%s.__oTerminatedLock" %
                                        oSelf.__class__.__name__,
                                        bLocked=True)

        oSelf.fAddEvents(
            "connect failed",
            "new connection",
            "request sent",
            "response received",
            "request sent and response received",
            "connection terminated",
            "terminated",
        )
Example #6
0
 def __init__(oSelf,
   ftxRequestHandler,
   szHostname = zNotProvided, uzPort = zNotProvided,
   o0SSLContext = None,
   n0zTransactionTimeoutInSeconds = zNotProvided,
   n0zIdleTimeoutInSeconds = zNotProvided,
 ):
   assert not fbIsProvided(szHostname) or isinstance(szHostname,  (str, unicode)), \
       "Invalid szHostname %s" % repr(szHostname);
   assert not fbIsProvided(uzPort) or isinstance(uzPort,  (int, long)), \
       "Invalid uPort %s" % repr(uzPort);
   oSelf.__ftxRequestHandler = ftxRequestHandler;
   oSelf.__n0TransactionTimeoutInSeconds = fxGetFirstProvidedValue(n0zTransactionTimeoutInSeconds, oSelf.n0DefaultTransactionTimeoutInSeconds);
   oSelf.__n0IdleTimeoutInSeconds = fxGetFirstProvidedValue(n0zIdleTimeoutInSeconds, oSelf.n0DefaultIdleTimeoutInSeconds);
   
   oSelf.__oPropertyAccessTransactionLock = cLock(
     "%s.__oPropertyAccessTransactionLock" % oSelf.__class__.__name__,
     n0DeadlockTimeoutInSeconds = gnDeadlockTimeoutInSeconds
   );
   
   oSelf.__aoConnections = [];
   oSelf.__aoConnectionThreads = [];
   
   oSelf.__bStopping = False;
   oSelf.__oTerminatedLock = cLock(
     "%s.__oTerminatedLock" % oSelf.__class__.__name__,
     bLocked = True
   );
   
   oSelf.fAddEvents(
     "new connection",
     "idle timeout",
     "request error", "request received",
     "response error", "response sent",
     "request received and response sent",
     "connection terminated",
     "terminated"
   );
   
   oSelf.__oConnectionAcceptor = cHTTPConnectionAcceptor(
     fNewConnectionHandler = oSelf.__fHandleNewConnection,
     szHostname = szHostname,
     uzPort = uzPort,
     o0SSLContext = o0SSLContext,
     n0zSecureTimeoutInSeconds = oSelf.__n0TransactionTimeoutInSeconds,
   );
   oSelf.__oConnectionAcceptor.fAddCallback("terminated", oSelf.__HandleTerminatedCallbackFromConnectionAcceptor);
Example #7
0
    def __init__(oSelf):
        assert os.path.isdir(oSelf.__sOpenSSLFolderPath), \
            "Cannot find OpenSSL folder %s; please download OpenSSL.exe into this folder." % oSelf.__sOpenSSLFolderPath
        assert os.path.isfile(oSelf.__sOpenSSLBinaryPath), \
            "Cannot find OpenSSL binary %s; please download OpenSSL.exe into this folder." % oSelf.__sOpenSSLBinaryPath

        assert os.path.isdir(oSelf.__sOpenSSLCertificateAuthorityFolderPath), \
            "Cannot find OpenSSL Certificate Authority folder %s" % oSelf.__sOpenSSLCertificateAuthorityFolderPath
        assert os.path.isfile(oSelf.__sOpenSSLIntermediateConfigFilePath), \
            "Cannot find OpenSSL intermediate config file %s" % oSelf.__sOpenSSLIntermediateConfigFilePath
        assert os.path.isfile(oSelf.__sOpenSSLCACertificatesFilePath), \
            "Cannot find OpenSSL CA Certificates file %s" % oSelf.__sOpenSSLCACertificatesFilePath

        oSelf.__oCacheLock = cLock(
            "%s.__oCacheLock" % oSelf.__class__.__name__,
            n0DeadlockTimeoutInSeconds=gnDeadlockTimeoutInSeconds)
        oSelf.__doCachedSSLContext_by_sHostname = {}

        if not os.path.isdir(oSelf.__sGeneratedCertificatesDatabaseFolderPath):
            os.mkdir(oSelf.__sGeneratedCertificatesDatabaseFolderPath)
            oSelf.fReset()
Example #8
0
    def __init__(
        oSelf,
        oProxyServerURL,
        bAllowUnverifiableCertificatesForProxy=False,
        bCheckProxyHostname=True,
        o0zCertificateStore=zNotProvided,
        u0zMaxNumberOfConnectionsToProxy=zNotProvided,
        n0zConnectToProxyTimeoutInSeconds=zNotProvided,
        n0zSecureConnectionToProxyTimeoutInSeconds=zNotProvided,
        n0zSecureConnectionToServerTimeoutInSeconds=zNotProvided,
        n0zTransactionTimeoutInSeconds=zNotProvided,
        bAllowUnverifiableCertificates=False,
        bCheckHostname=True,
    ):
        oSelf.oProxyServerURL = oProxyServerURL
        oSelf.__bAllowUnverifiableCertificatesForProxy = bAllowUnverifiableCertificatesForProxy
        oSelf.__bCheckProxyHostname = bCheckProxyHostname

        oSelf.__o0CertificateStore = (
            o0zCertificateStore if fbIsProvided(o0zCertificateStore) else
            c0CertificateStore() if c0CertificateStore is not None else None)
        assert not oProxyServerURL.bSecure or oSelf.__o0CertificateStore, \
            "Cannot use a secure proxy without the mSSL module!"
        oSelf.__u0MaxNumberOfConnectionsToProxy = fxGetFirstProvidedValue(
            u0zMaxNumberOfConnectionsToProxy,
            oSelf.u0DefaultMaxNumberOfConnectionsToProxy)
        # Timeouts for this instance default to the timeouts specified for the class.
        oSelf.__n0zConnectToProxyTimeoutInSeconds = fxzGetFirstProvidedValueIfAny(
            n0zConnectToProxyTimeoutInSeconds,
            oSelf.n0zDefaultConnectToProxyTimeoutInSeconds)
        oSelf.__n0zSecureConnectionToProxyTimeoutInSeconds = fxzGetFirstProvidedValueIfAny(
            n0zSecureConnectionToProxyTimeoutInSeconds,
            oSelf.n0zDefaultSecureConnectionToProxyTimeoutInSeconds)
        oSelf.__n0zSecureConnectionToServerTimeoutInSeconds = fxzGetFirstProvidedValueIfAny(
            n0zSecureConnectionToServerTimeoutInSeconds,
            oSelf.n0zDefaultSecureConnectionToServerTimeoutInSeconds)
        oSelf.__n0TransactionTimeoutInSeconds = fxGetFirstProvidedValue(
            n0zTransactionTimeoutInSeconds,
            oSelf.n0DefaultTransactionTimeoutInSeconds)
        oSelf.__bAllowUnverifiableCertificates = bAllowUnverifiableCertificates
        oSelf.__bCheckHostname = bCheckHostname

        if not oProxyServerURL.bSecure:
            oSelf.__o0ProxySSLContext = None
        else:
            assert oSelf.__o0CertificateStore, \
                "A secure proxy cannot be used if no certificate store is available!"
            if bAllowUnverifiableCertificatesForProxy:
                oSelf.__o0ProxySSLContext = oSelf.__o0CertificateStore.foGetClientsideSSLContextWithoutVerification(
                )
            else:
                oSelf.__o0ProxySSLContext = oSelf.__o0CertificateStore.foGetClientsideSSLContextForHostname(
                    oProxyServerURL.sHostname,
                    oSelf.__bCheckProxyHostname,
                )

        oSelf.__oWaitingForConnectionToBecomeAvailableLock = cLock(
            "%s.__oWaitingForConnectionToBecomeAvailableLock" %
            oSelf.__class__.__name__, )

        oSelf.__oPropertyAccessTransactionLock = cLock(
            "%s.__oPropertyAccessTransactionLock" % oSelf.__class__.__name__,
            n0DeadlockTimeoutInSeconds=gnDeadlockTimeoutInSeconds)
        oSelf.__aoConnectionsToProxyNotConnectedToAServer = []
        oSelf.__doConnectionToProxyUsedForSecureConnectionToServer_by_sProtocolHostPort = {}
        oSelf.__doSecureConnectionToServerThroughProxy_by_sProtocolHostPort = {}

        oSelf.__bStopping = False
        oSelf.__oTerminatedLock = cLock("%s.__oTerminatedLock" %
                                        oSelf.__class__.__name__,
                                        bLocked=True)

        oSelf.fAddEvents(
            "connect failed",
            "new connection",  # connect failed currently does not fire: assertions are triggered instead.
            "request sent",
            "response received",
            "request sent and response received",
            "secure connection established",
            "connection terminated",
            "terminated",
        )
    def __init__(
        oSelf,
        szHostname=zNotProvided,
        uzPort=zNotProvided,
        o0ServerSSLContext=None,
        o0zCertificateStore=zNotProvided,
        o0ChainedProxyURL=None,
        o0ChainedProxyHTTPClient=None,
        bAllowUnverifiableCertificatesForChainedProxy=False,
        bCheckChainedProxyHostname=True,
        u0zMaxNumberOfConnectionsToChainedProxy=zNotProvided,
        # Connections to proxy use nzConnectTimeoutInSeconds
        n0zSecureConnectionToChainedProxyTimeoutInSeconds=zNotProvided,
        # Connections to proxy use nzTransactionTimeoutInSeconds
        o0InterceptSSLConnectionsCertificateAuthority=None,
        n0zConnectTimeoutInSeconds=zNotProvided,
        n0zSecureTimeoutInSeconds=zNotProvided,
        n0zTransactionTimeoutInSeconds=zNotProvided,
        bAllowUnverifiableCertificates=False,
        bCheckHostname=True,
        n0zSecureConnectionPipeTotalDurationTimeoutInSeconds=zNotProvided,
        n0zSecureConnectionPipeIdleTimeoutInSeconds=zNotProvided,
        u0zMaxNumberOfConnectionsToServer=zNotProvided,
    ):
        oSelf.__o0InterceptSSLConnectionsCertificateAuthority = o0InterceptSSLConnectionsCertificateAuthority
        oSelf.__n0zConnectTimeoutInSeconds = n0zConnectTimeoutInSeconds
        oSelf.__n0zSecureTimeoutInSeconds = fxzGetFirstProvidedValueIfAny(
            n0zSecureTimeoutInSeconds, oSelf.n0DefaultSecureTimeoutInSeconds)
        oSelf.__n0zTransactionTimeoutInSeconds = fxzGetFirstProvidedValueIfAny(
            n0zTransactionTimeoutInSeconds,
            oSelf.n0DefaultTransactionTimeoutInSeconds)
        oSelf.__bAllowUnverifiableCertificates = bAllowUnverifiableCertificates
        oSelf.__bCheckHostname = bCheckHostname
        oSelf.__n0SecureConnectionPipeTotalDurationTimeoutInSeconds = fxGetFirstProvidedValue( \
            n0zSecureConnectionPipeTotalDurationTimeoutInSeconds, oSelf.n0DefaultSecureConnectionPipeTotalDurationTimeoutInSeconds)
        oSelf.__n0SecureConnectionPipeIdleTimeoutInSeconds = fxGetFirstProvidedValue( \
            n0zSecureConnectionPipeIdleTimeoutInSeconds, oSelf.n0DefaultSecureConnectionPipeIdleTimeoutInSeconds)

        oSelf.__oPropertyAccessTransactionLock = cLock(
            "%s.__oPropertyAccessTransactionLock" % oSelf.__class__.__name__,
            n0DeadlockTimeoutInSeconds=gnDeadlockTimeoutInSeconds)
        oSelf.__aoSecureConnectionsFromClient = []
        oSelf.__aoSecureConnectionThreads = []

        oSelf.__bStopping = False
        oSelf.__oTerminatedLock = cLock("%s.__oTerminatedLock" %
                                        oSelf.__class__.__name__,
                                        bLocked=True)

        oSelf.fAddEvents(
            "new connection from client", "connect to server failed",
            "new connection to server", "request received from client",
            "request sent to server",
            "connection piped between client and server",
            "connection intercepted between client and server",
            "response received from server", "response sent to client",
            "request sent to and response received from server",
            "request received from and response sent to client",
            "connection to server terminated",
            "connection from client terminated", "client terminated",
            "server terminated", "terminated")

        # Create client
        if o0ChainedProxyHTTPClient:
            assert not o0ChainedProxyURL, \
                "Cannot provide both a chained proxy URL (%s) and HTTP client (%s)" % \
                (o0ChainedProxyURL, o0ChainedProxyHTTPClient)
            # Ideally, we want to check the caller did not provide any unapplicable arguments here, but that's a lot of
            # work, so I've pushed this out until it makes sense to add these checks
            oSelf.oHTTPClient = o0ChainedProxyHTTPClient
            oSelf.__bUsingChainedProxy = True
        elif o0ChainedProxyURL:
            # Ideally, we want to check the caller did not provide any unapplicable arguments here, but that's a lot of
            # work, so I've pushed this out until it makes sense to add these checks
            oSelf.oHTTPClient = cHTTPClientUsingProxyServer(
              oProxyServerURL = o0ChainedProxyURL,
              bAllowUnverifiableCertificatesForProxy = bAllowUnverifiableCertificatesForChainedProxy,
              bCheckProxyHostname = bCheckChainedProxyHostname,
              o0zCertificateStore = o0zCertificateStore,
              u0zMaxNumberOfConnectionsToProxy = fxGetFirstProvidedValue( \
                  u0zMaxNumberOfConnectionsToChainedProxy, oSelf.u0DefaultMaxNumberOfConnectionsToChainedProxy),
              n0zConnectToProxyTimeoutInSeconds = n0zConnectTimeoutInSeconds,
              n0zSecureConnectionToProxyTimeoutInSeconds = fxGetFirstProvidedValue( \
                  n0zSecureConnectionToChainedProxyTimeoutInSeconds, oSelf.n0DefaultSecureConnectionToChainedProxyTimeoutInSeconds),
              n0zSecureConnectionToServerTimeoutInSeconds = oSelf.__n0zSecureTimeoutInSeconds,
              n0zTransactionTimeoutInSeconds = oSelf.__n0zTransactionTimeoutInSeconds,
              bAllowUnverifiableCertificates = bAllowUnverifiableCertificates,
              bCheckHostname = bCheckHostname,
            )
            oSelf.__bUsingChainedProxy = True
        else:
            # Ideally, we want to check the caller did not provide any unapplicable arguments here, but that's a lot of
            # work, so I've pushed this out until it makes sense to add these checks
            oSelf.oHTTPClient = cHTTPClient(
                o0zCertificateStore=o0zCertificateStore,
                u0zMaxNumberOfConnectionsToServer=
                u0zMaxNumberOfConnectionsToServer,
                n0zConnectTimeoutInSeconds=n0zConnectTimeoutInSeconds,
                n0zSecureTimeoutInSeconds=oSelf.__n0zSecureTimeoutInSeconds,
                n0zTransactionTimeoutInSeconds=oSelf.
                __n0zTransactionTimeoutInSeconds,
                bAllowUnverifiableCertificates=bAllowUnverifiableCertificates,
                bCheckHostname=bCheckHostname,
            )
            oSelf.__bUsingChainedProxy = False
        # Create server
        oSelf.oHTTPServer = cHTTPServer(
            ftxRequestHandler=oSelf.__ftxRequestHandler,
            szHostname=szHostname,
            uzPort=uzPort,
            o0SSLContext=o0ServerSSLContext,
        )

        # Forward events from client
        oSelf.oHTTPClient.fAddCallback(
            "connect failed", lambda oHTTPServer,
            sHostname, uPort, oException: oSelf.fFireCallbacks(
                "connect to server failed", sHostname, uPort, oException))
        oSelf.oHTTPClient.fAddCallback(
            "new connection",
            lambda oHTTPServer, oConnection: oSelf.fFireCallbacks(
                "new connection to server", oConnection))
        oSelf.oHTTPClient.fAddCallback(
            "request sent",
            lambda oHTTPServer, oConnection, oRequest: oSelf.fFireCallbacks(
                "request sent to server", oConnection, oRequest))
        oSelf.oHTTPClient.fAddCallback(
            "response received",
            lambda oHTTPServer, oConnection, oResponse: oSelf.fFireCallbacks(
                "response received from server", oConnection, oResponse))
        oSelf.oHTTPClient.fAddCallback(
            "request sent and response received",
            lambda oHTTPServer, oConnection, oRequest, oResponse: oSelf.
            fFireCallbacks("request sent to and response received from server",
                           oConnection, oRequest, oResponse))
        oSelf.oHTTPClient.fAddCallback(
            "connection terminated",
            lambda oHTTPServer, oConnection: oSelf.fFireCallbacks(
                "connection to server terminated", oConnection))
        oSelf.oHTTPClient.fAddCallback(
            "terminated", oSelf.__fHandleTerminatedCallbackFromClient)

        # Forward events from server
        oSelf.oHTTPServer.fAddCallback(
            "new connection",
            lambda oHTTPServer, oConnection: oSelf.fFireCallbacks(
                "new connection from client", oConnection))
        oSelf.oHTTPServer.fAddCallback(
            "request received",
            lambda oHTTPServer, oConnection, oRequest: oSelf.fFireCallbacks(
                "request received from client", oConnection, oRequest))
        oSelf.oHTTPServer.fAddCallback(
            "response sent",
            lambda oHTTPServer, oConnection, oResponse: oSelf.fFireCallbacks(
                "response sent to client", oConnection, oResponse))
        oSelf.oHTTPServer.fAddCallback(
            "request received and response sent",
            lambda oHTTPServer, oConnection, oRequest, oResponse: oSelf.
            fFireCallbacks("request received from and response sent to client",
                           oConnection, oRequest, oResponse))
        oSelf.oHTTPServer.fAddCallback(
            "connection terminated",
            lambda oHTTPServer, oConnection: oSelf.fFireCallbacks(
                "connection from client terminated", oConnection))
        oSelf.oHTTPServer.fAddCallback(
            "terminated", oSelf.__fHandleTerminatedCallbackFromServer)
Example #10
0
 def __init__(oSelf,
              oConsole,
              sHostname,
              uPort,
              sName,
              bListen=True,
              bAccept=True,
              u0MinRequestBytes=None,
              u0MaxRequestBytes=None,
              s0Response=None,
              bShutdownForReading=False,
              bShutdownForWriting=False,
              bDisconnect=False):
     oSelf.oConsole = oConsole
     # not imported but passed as an argument because it may not be available, in which case a stub is used.
     oSelf.sHostname = sHostname
     oSelf.uPort = uPort
     oSelf.sName = sName
     oSelf.oServerSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM,
                                         0)
     #    oSelf.oServerSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1); # Do not go to TIME_WAIT after close.
     oSelf.oConsole.fOutput(
         DIM, "* ", oSelf.sName,
         " test server: binding to %s:%d..." % (sHostname, uPort))
     oSelf.oServerSocket.bind((sHostname, uPort))
     oSelf.bListening = bListen
     oSelf.bAccepting = bListen and bAccept
     oSelf.oTerminatedLock = cLock("Terminated lock", bLocked=True)
     if not bListen:
         oSelf.oConsole.fOutput(DIM, "* ", oSelf.sName,
                                " test server: closing server socket...")
         oSelf.oServerSocket.close()
     else:
         oSelf.bStopping = False
         # If we are accepting connections, allow the next connection to be queued while we're handling the current
         # connection (see below)
         oSelf.oConsole.fOutput(DIM, "* ", oSelf.sName,
                                " test server: listening...")
         oSelf.oServerSocket.listen(1 if bAccept else 0)
         oSelf.u0MinRequestBytes = u0MinRequestBytes
         if u0MinRequestBytes is not None:
             assert bAccept, "Cannot have `bAccept is False` and `u0MinRequestBytes is not None`!"
             assert u0MaxRequestBytes is not None, "Cannot have `u0MinRequestBytes is not None` if `u0MaxRequestBytes is None`!"
             oSelf.uMaxRequestBytes = u0MaxRequestBytes
         assert bAccept or s0Response is None, "Cannot have `bAccept is False` and `s0Response is not None`!"
         oSelf.s0Response = s0Response
         assert bAccept or not bShutdownForReading, "Cannot have `bAccept is False` and `bShutdownForReading is True`!"
         oSelf.bShutdownForReading = bShutdownForReading
         assert bAccept or not bShutdownForWriting, "Cannot have `bAccept is False` and `bShutdownForWriting is True`!"
         oSelf.bShutdownForWriting = bShutdownForWriting
         assert bAccept or not bShutdownForWriting, "Cannot have `bAccept is False` and `bDisconnect is True`!"
         oSelf.bDisconnect = bDisconnect
         if not bAccept:
             # If we are NOT accepting connections, make a connection to the server but we do not
             # accept it. Further connections cannot be made until it is accepted but will be queued
             # This is because we've told the socket not to queue additional connections (see above).
             oSelf.oHelperClientSocket = socket.socket(
                 socket.AF_INET, socket.SOCK_STREAM, 0)
             oSelf.oHelperClientSocket.connect((sHostname, uPort))
             oSelf.oConsole.fOutput(
                 DIM, "* ", oSelf.sName,
                 " test server: NOT accepting connections...")
         else:
             oSelf.oServerThreadStartedLock = cLock(
                 "Server thread started lock", bLocked=True)
             oSelf.oServerThread = cThread(oSelf.fServerThread)
             oSelf.oServerThread.fStart(bVital=False)
             oSelf.oServerThreadStartedLock.fWait()
Example #11
0
 def __init__(oSelf,
   o0zCertificateStore = zNotProvided, 
   bAllowUnverifiableCertificatesForProxy = False, bCheckProxyHostname = True,
   u0zMaxNumberOfConnectionsToServerWithoutProxy = zNotProvided,
   u0zMaxNumberOfConnectionsToProxy = zNotProvided,
   n0zConnectTimeoutInSeconds = zNotProvided, n0zSecureTimeoutInSeconds = zNotProvided, n0zTransactionTimeoutInSeconds = zNotProvided,
   n0zConnectToProxyTimeoutInSeconds = zNotProvided, n0zSecureConnectionToProxyTimeoutInSeconds = zNotProvided,
   n0zSecureConnectionToServerTimeoutInSeconds = zNotProvided,
   bAllowUnverifiableCertificates = False, bCheckHostname = True,
 ):
   oSelf.__hInternet = oWinHTTPDLL.WinHttpOpen(
     LPCWSTR("User-Agent"), # LPCWSTR pszAgentW
     WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY, # DWORD dwAccessType
     WINHTTP_NO_PROXY_NAME, # LPCWSTR pszProxyW
     WINHTTP_NO_PROXY_BYPASS, # LPCWSTR pszProxyBypassW
     NULL, # DWORD dwFlags
   );
   if oSelf.__hInternet == NULL:
     oKernel32 = foLoadKernel32DLL();
     odwLastError = oKernel32.GetLastError();
     raise AssertionError("Cannot initialize WinHTTP: error 0x%X" % (odwLastError.value,));
   # This code will instantiate other classes to make requests. A single certificate store instance is used by all
   # these instances.
   oSelf.__o0CertificateStore = (
     o0zCertificateStore if fbIsProvided(o0zCertificateStore) else
     c0CertificateStore() if c0CertificateStore else
     None
   );
   oSelf.__bAllowUnverifiableCertificatesForProxy = bAllowUnverifiableCertificatesForProxy;
   oSelf.__bCheckProxyHostname = bCheckProxyHostname;
   #
   oSelf.__u0zMaxNumberOfConnectionsToServerWithoutProxy = fxzGetFirstProvidedValueIfAny(u0zMaxNumberOfConnectionsToServerWithoutProxy, oSelf.u0zDefaultMaxNumberOfConnectionsToServerWithoutProxy);
   #
   oSelf.__u0zMaxNumberOfConnectionsToProxy = fxzGetFirstProvidedValueIfAny(u0zMaxNumberOfConnectionsToProxy, oSelf.u0zDefaultMaxNumberOfConnectionsToProxy);
   # Timeouts can be provided through class default, instance defaults, or method call arguments.
   oSelf.__n0zConnectTimeoutInSeconds = fxzGetFirstProvidedValueIfAny(n0zConnectTimeoutInSeconds, oSelf.n0zDefaultConnectTimeoutInSeconds);
   oSelf.__n0zSecureTimeoutInSeconds = fxzGetFirstProvidedValueIfAny(n0zSecureTimeoutInSeconds, oSelf.n0zDefaultSecureTimeoutInSeconds);
   oSelf.__n0zTransactionTimeoutInSeconds = fxzGetFirstProvidedValueIfAny(n0zTransactionTimeoutInSeconds, oSelf.n0zDefaultTransactionTimeoutInSeconds);
   #
   oSelf.__n0zConnectToProxyTimeoutInSeconds = fxzGetFirstProvidedValueIfAny(n0zConnectToProxyTimeoutInSeconds, oSelf.n0zDefaultConnectToProxyTimeoutInSeconds);
   oSelf.__n0zSecureConnectionToProxyTimeoutInSeconds = fxzGetFirstProvidedValueIfAny(n0zSecureConnectionToProxyTimeoutInSeconds, oSelf.n0zDefaultSecureConnectionToProxyTimeoutInSeconds);
   #
   oSelf.__n0zSecureConnectionToServerTimeoutInSeconds = fxzGetFirstProvidedValueIfAny(n0zSecureConnectionToServerTimeoutInSeconds, oSelf.n0zDefaultSecureConnectionToServerTimeoutInSeconds);
   #
   oSelf.__bAllowUnverifiableCertificates = bAllowUnverifiableCertificates;
   oSelf.__bCheckHostname = bCheckHostname;
   #############################
   oSelf.__oPropertyAccessTransactionLock = cLock(
     "%s.__oPropertyAccessTransactionLock" % oSelf.__class__.__name__,
     n0DeadlockTimeoutInSeconds = gnDeadlockTimeoutInSeconds
   );
   oSelf.__oDirectHTTPClient = None;
   oSelf.__doHTTPClientUsingProxyServer_by_sLowerProxyServerURL = {};
   
   oSelf.__bStopping = False;
   oSelf.__oTerminatedLock = cLock("%s.__oTerminatedLock" % oSelf.__class__.__name__, bLocked = True);
   
   oSelf.fAddEvents(
     "proxy selected",
     "new direct client", "new client using proxy server",
     "connect failed", "new connection",
     "request sent", "response received", "request sent and response received",
     "secure connection established",
     "connection terminated",
     "direct client terminated", "client using proxy server terminated",
     "terminated",
   );
Example #12
0
from .cSSLContext import cSSLContext

from mMultiThreading import cLock

gsMainFolderPath = os.path.dirname(__file__)
# To turn access to data store in multiple variables into a single transaction, we will create locks.
# These locks should only ever be locked for a short time; if it is locked for too long, it is considered a "deadlock"
# bug, where "too long" is defined by the following value:
gnDeadlockTimeoutInSeconds = 30
# We will be accessing files and executing code, so this should suffice.
# Since we can generate these files, we need a lock to prevent race conditions when
# two files want to generate a certificate for the same hostname.
goCertificateFilesLock = cLock(
    "cCertificateAuthority.py/goCertificateFilesLock",
    # If this lock is held for a long enough time while another thread is attempting to acquire it, report an error:
    n0DeadlockTimeoutInSeconds=gnDeadlockTimeoutInSeconds,
)

dGeneratedCertificatesDatabaseFile_sResetContent_by_sName = {
    "intermediate-database": "",
    "intermediate-serial": "0000",
}


class cCertificateAuthority(object):
    __sOpenSSLFolderPath = os.path.join(gsMainFolderPath, "OpenSSL")
    __sOpenSSLBinaryPath = os.path.join(__sOpenSSLFolderPath, "OpenSSL.exe")

    __sOpenSSLCertificateAuthorityFolderPath = os.path.join(
        gsMainFolderPath, "CA")