Ejemplo n.º 1
0
    def _newClientConnection(self):
        """
        Create a new client connection.

        @return: A L{Deferred} that fires with the L{IProtocol} instance.
        """
        self.log.debug(
            "Initiating new client connection to: %r" % (self._endpoint,)
        )
        self._logClientStats()

        self._pendingConnects += 1

        def _connected(client):
            self._pendingConnects -= 1

            return client

        factory = self.clientFactory()
        factory.noisy = False

        factory.connectionPool = self

        connect(self._endpoint, factory)
        d = factory.deferred

        d.addCallback(_connected)
        return d
Ejemplo n.º 2
0
    def _newClientConnection(self):
        """
        Create a new client connection.

        @return: A L{Deferred} that fires with the L{IProtocol} instance.
        """
        self.log.debug(
            "Initiating new client connection to: {r!r}", r=self._endpoint
        )
        self._logClientStats()

        self._pendingConnects += 1

        def _connected(client):
            self._pendingConnects -= 1

            return client

        factory = self.clientFactory()
        factory.noisy = False

        factory.connectionPool = self

        connect(self._endpoint, factory)
        d = factory.deferred

        d.addCallback(_connected)
        return d
Ejemplo n.º 3
0
    def startMonitoring(self, host, port, nodes):
        service = "pubsub.%s" % (host, )
        jid = "%s@%s" % (self.authname, host)

        pubsubFactory = PubSubClientFactory(jid, self.password, service, nodes,
                                            self.verbose)
        connect(GAIEndpoint(reactor, host, port), pubsubFactory)
Ejemplo n.º 4
0
    def startMonitoring(self, host, port, nodes):
        service = "pubsub.%s" % (host,)
        jid = "%s@%s" % (self.authname, host)

        pubsubFactory = PubSubClientFactory(jid, self.password, service, nodes,
            self.verbose)
        connect(GAIEndpoint(reactor, host, port), pubsubFactory)
Ejemplo n.º 5
0
    def sendMessage(self, fromAddr, toAddr, msgId, message):

        log.debug("Sending: {msg}", msg=message)

        def _success(result, msgId, fromAddr, toAddr):
            log.info(
                "Sent IMIP message {id} from {fr} to {to}",
                id=msgId,
                fr=fromAddr,
                to=toAddr,
            )
            return True

        def _failure(failure, msgId, fromAddr, toAddr):
            log.error(
                "Failed to send IMIP message {id} from {fr} to {to} (Reason: {err})",
                id=msgId,
                fr=fromAddr,
                to=toAddr,
                err=failure.getErrorMessage(),
            )
            from OpenSSL.SSL import Error as TLSError
            if failure.type is TLSError:
                from calendarserver.tap.util import AlertPoster
                AlertPoster.postAlert("MailCertificateAlert", 7 * 24 * 60 * 60,
                                      [])
            return False

        deferred = defer.Deferred()

        if self.useSSL:
            contextFactory = simpleClientContextFactory(self.server)
        else:
            contextFactory = None

        factory = ESMTPSenderFactory(
            self.username,
            self.password,
            fromAddr,
            toAddr,
            # per http://trac.calendarserver.org/ticket/416 ...
            StringIO(message.replace("\r\n", "\n")),
            deferred,
            contextFactory=contextFactory,
            requireAuthentication=False,
            requireTransportSecurity=self.useSSL)

        connect(GAIEndpoint(_reactor, self.server, self.port), factory)
        deferred.addCallback(_success, msgId, fromAddr, toAddr)
        deferred.addErrback(_failure, msgId, fromAddr, toAddr)
        return deferred
Ejemplo n.º 6
0
    def makeRequest(self, path, method, headers, body):
        scheme = "https:" if self.useSSL else "http:"
        url = "%s//%s:%d%s" % (scheme, self.host, self.port, path)
        caldavFactory = client.HTTPClientFactory(url, method=method,
            headers=headers, postdata=body, agent="Push Monitor")
        caldavFactory.username = self.authname
        caldavFactory.password = self.password
        caldavFactory.noisy = False
        caldavFactory.protocol = PropfindRequestor
        if self.useSSL:
            connect(GAIEndpoint(reactor, self.host, self.port,
                                self.ClientContextFactory()),
                    caldavFactory)
        else:
            connect(GAIEndpoint(reactor, self.host, self.port), caldavFactory)

        return caldavFactory.deferred
Ejemplo n.º 7
0
    def makeRequest(self, path, method, headers, body):
        scheme = "https:" if self.useSSL else "http:"
        url = "%s//%s:%d%s" % (scheme, self.host, self.port, path)
        caldavFactory = client.HTTPClientFactory(url, method=method,
            headers=headers, postdata=body, agent="Push Monitor")
        caldavFactory.username = self.authname
        caldavFactory.password = self.password
        caldavFactory.noisy = False
        caldavFactory.protocol = PropfindRequestor
        if self.useSSL:
            connect(GAIEndpoint(reactor, self.host, self.port,
                                self.ClientContextFactory()),
                    caldavFactory)
        else:
            connect(GAIEndpoint(reactor, self.host, self.port), caldavFactory)

        return caldavFactory.deferred
Ejemplo n.º 8
0
 def connect(self, factory):
     if self.testConnector is not None:
         # For testing purposes
         self.testConnector.connect(self, factory)
     else:
         if self.passphrase:
             passwdCallback = lambda *ignored: self.passphrase
         else:
             passwdCallback = None
         context = ChainingOpenSSLContextFactory(
             self.keyPath,
             self.certPath,
             certificateChainFile=self.chainPath,
             passwdCallback=passwdCallback,
             sslmethod=getattr(OpenSSL.SSL, self.sslMethod))
         connect(GAIEndpoint(self.reactor, self.host, self.port, context),
                 factory)
Ejemplo n.º 9
0
def _getPage(url, host, port):
    """
    Fetch the body of the given url via HTTP, connecting to the given host
    and port.

    @param url: The URL to GET
    @type url: C{str}
    @param host: The hostname to connect to
    @type host: C{str}
    @param port: The port number to connect to
    @type port: C{int}
    @return: A deferred; upon 200 success the body of the response is returned,
        otherwise a twisted.web.error.Error is the result.
    """
    factory = HTTPClientFactory(url)
    factory.protocol = HTTPPageGetter
    connect(GAIEndpoint(reactor, host, port), factory)
    return factory.deferred
Ejemplo n.º 10
0
 def connect(self, factory):
     if self.testConnector is not None:
         # For testing purposes
         self.testConnector.connect(self, factory)
     else:
         if self.passphrase:
             passwdCallback = lambda *ignored : self.passphrase
         else:
             passwdCallback = None
         context = ChainingOpenSSLContextFactory(
             self.keyPath,
             self.certPath,
             certificateChainFile=self.chainPath,
             passwdCallback=passwdCallback,
             sslmethod=getattr(OpenSSL.SSL, self.sslMethod)
         )
         connect(GAIEndpoint(self.reactor, self.host, self.port, context),
                 factory)
Ejemplo n.º 11
0
    def _newClientConnection(self):
        """
        Create a new client connection.

        @return: A L{Deferred} that fires with the L{IProtocol} instance.
        """
        self._pendingConnects += 1

        self.log.debug(
            "Initiating new client connection to: {endpoint!r}",
            endpoint=self._endpoint,
        )
        self._logClientStats()

        factory = self.clientFactory(self._reactor)
        factory.connectionPool = self

        if self._scheme == "https":
            connect(self._secureEndpoint, factory)
        elif self._scheme == "http":
            connect(self._endpoint, factory)
        else:
            raise ValueError("URL scheme for client pool not supported")

        def _doneOK(client):
            self._pendingConnects -= 1

            def _goneClientAfterError(f, client):
                f.trap(ConnectionLost, ConnectionDone, ConnectError)
                self.clientGone(client)

            d2 = factory.afterConnect
            d2.addErrback(_goneClientAfterError, client)
            return client

        def _doneError(result):
            self._pendingConnects -= 1
            return result

        d = factory.onConnect
        d.addCallbacks(_doneOK, _doneError)

        return d
Ejemplo n.º 12
0
    def sendMessage(self, fromAddr, toAddr, msgId, message):

        log.debug("Sending: {msg}", msg=message)
        def _success(result, msgId, fromAddr, toAddr):
            log.info(
                "Sent IMIP message {id} from {fr} to {to}",
                id=msgId,
                fr=fromAddr,
                to=toAddr,
            )
            return True

        def _failure(failure, msgId, fromAddr, toAddr):
            log.error(
                "Failed to send IMIP message {id} from {fr} to {to} (Reason: {err})",
                id=msgId,
                fr=fromAddr,
                to=toAddr,
                err=failure.getErrorMessage(),
            )
            return False

        deferred = defer.Deferred()

        if self.useSSL:
            contextFactory = ssl.ClientContextFactory()
        else:
            contextFactory = None

        factory = ESMTPSenderFactory(
            self.username, self.password,
            fromAddr, toAddr,
            # per http://trac.calendarserver.org/ticket/416 ...
            StringIO(message.replace("\r\n", "\n")), deferred,
            contextFactory=contextFactory,
            requireAuthentication=False,
            requireTransportSecurity=self.useSSL)

        connect(GAIEndpoint(_reactor, self.server, self.port),
                factory)
        deferred.addCallback(_success, msgId, fromAddr, toAddr)
        deferred.addErrback(_failure, msgId, fromAddr, toAddr)
        return deferred
Ejemplo n.º 13
0
    def _newClientConnection(self):
        """
        Create a new client connection.

        @return: A L{Deferred} that fires with the L{IProtocol} instance.
        """
        self._pendingConnects += 1

        self.log.debug("Initating new client connection to: %r" % (
            self._endpoint,))
        self._logClientStats()

        factory = self.clientFactory(self._reactor)
        factory.connectionPool = self

        if self._scheme == "https":
            connect(self._secureEndpoint, factory)
        elif self._scheme == "http":
            connect(self._endpoint, factory)
        else:
            raise ValueError("URL scheme for client pool not supported")

        def _doneOK(client):
            self._pendingConnects -= 1

            def _goneClientAfterError(f, client):
                f.trap(ConnectionLost, ConnectionDone, ConnectError)
                self.clientGone(client)

            d2 = factory.afterConnect
            d2.addErrback(_goneClientAfterError, client)
            return client

        def _doneError(result):
            self._pendingConnects -= 1
            return result

        d = factory.onConnect
        d.addCallbacks(_doneOK, _doneError)

        return d
Ejemplo n.º 14
0
    def handleStatus_401(self):

        self.quietLoss = 1
        self.transport.loseConnection()

        if not hasattr(self.factory, "username"):
            self.factory.deferred.errback(failure.Failure(Unauthorized("Authentication required")))
            return self.factory.deferred

        if hasattr(self.factory, "retried"):
            self.factory.deferred.errback(failure.Failure(Unauthorized("Could not authenticate user %s with calendar server" % (self.factory.username,))))
            return self.factory.deferred

        self.factory.retried = True

        # self.log.debug("Got a 401 trying to inject [%s]" % (self.headers,))
        details = {}
        basicAvailable = digestAvailable = False
        wwwauth = self.headers.get("www-authenticate")
        for item in wwwauth:
            if item.startswith("basic "):
                basicAvailable = True
            if item.startswith("digest "):
                digestAvailable = True
                wwwauth = item[7:]
                def unq(s):
                    if s[0] == s[-1] == '"':
                        return s[1:-1]
                    return s
                parts = wwwauth.split(',')
                for (k, v) in [p.split('=', 1) for p in parts]:
                    details[k.strip()] = unq(v.strip())

        user = self.factory.username
        pswd = self.factory.password

        if digestAvailable and details:
            digest = calcResponse(
                calcHA1(
                    details.get('algorithm'),
                    user,
                    details.get('realm'),
                    pswd,
                    details.get('nonce'),
                    details.get('cnonce')
                ),
                details.get('algorithm'),
                details.get('nonce'),
                details.get('nc'),
                details.get('cnonce'),
                details.get('qop'),
                self.factory.method,
                self.factory.url,
                None
            )

            if details.get('qop'):
                response = (
                    'Digest username="******", realm="%s", nonce="%s", uri="%s", '
                    'response=%s, algorithm=%s, cnonce="%s", qop=%s, nc=%s' %
                    (
                        user,
                        details.get('realm'),
                        details.get('nonce'),
                        self.factory.url,
                        digest,
                        details.get('algorithm'),
                        details.get('cnonce'),
                        details.get('qop'),
                        details.get('nc'),
                    )
                )
            else:
                response = (
                    'Digest username="******", realm="%s", nonce="%s", uri="%s", '
                    'response=%s, algorithm=%s' %
                    (
                        user,
                        details.get('realm'),
                        details.get('nonce'),
                        self.factory.url,
                        digest,
                        details.get('algorithm'),
                    )
                )

            self.factory.headers['Authorization'] = response

            if self.factory.scheme == 'https':
                connect(
                    GAIEndpoint(reactor, self.factory.host, self.factory.port,
                                ssl.ClientContextFactory()),
                    self.factory)
            else:
                connect(
                    GAIEndpoint(reactor, self.factory.host, self.factory.port),
                    self.factory)
            # self.log.debug("Retrying with digest after 401")

            return self.factory.deferred

        elif basicAvailable:
            basicauth = "%s:%s" % (user, pswd)
            basicauth = "Basic " + base64.encodestring(basicauth)
            basicauth = basicauth.replace("\n", "")

            self.factory.headers['Authorization'] = basicauth

            if self.factory.scheme == 'https':
                connect(
                    GAIEndpoint(reactor, self.factory.host, self.factory.port,
                                ssl.ClientContextFactory()),
                    self.factory)
            else:
                connect(
                    GAIEndpoint(reactor, self.factory.host, self.factory.port),
                    self.factory)
            # self.log.debug("Retrying with basic after 401")

            return self.factory.deferred

        else:
            self.factory.deferred.errback(failure.Failure(Unauthorized("Mail gateway not able to process reply; calendar server returned 401 and doesn't support basic or digest")))
            return self.factory.deferred
Ejemplo n.º 15
0
 def setUp(self):
     self.factory = RecordingClientFactory()
     self.endpoint = RecordingEndpoint()
     self.connector = connect(self.endpoint, self.factory)
Ejemplo n.º 16
0
    def handleStatus_401(self):

        self.quietLoss = 1
        self.transport.loseConnection()

        if not hasattr(self.factory, "username"):
            self.factory.deferred.errback(
                failure.Failure(Unauthorized("Authentication required")))
            return self.factory.deferred

        if hasattr(self.factory, "retried"):
            self.factory.deferred.errback(
                failure.Failure(
                    Unauthorized(
                        "Could not authenticate user %s with calendar server" %
                        (self.factory.username, ))))
            return self.factory.deferred

        self.factory.retried = True

        # self.log.debug("Got a 401 trying to inject [{hdrs}]", hdrs=self.headers)
        details = {}
        basicAvailable = digestAvailable = False
        wwwauth = self.headers.get("www-authenticate")
        for item in wwwauth:
            if item.startswith("basic "):
                basicAvailable = True
            if item.startswith("digest "):
                digestAvailable = True
                wwwauth = item[7:]

                def unq(s):
                    if s[0] == s[-1] == '"':
                        return s[1:-1]
                    return s

                parts = wwwauth.split(',')
                for (k, v) in [p.split('=', 1) for p in parts]:
                    details[k.strip()] = unq(v.strip())

        user = self.factory.username
        pswd = self.factory.password

        if digestAvailable and details:
            digest = calcResponse(
                calcHA1(details.get('algorithm'), user,
                        details.get('realm'), pswd, details.get('nonce'),
                        details.get('cnonce')), details.get('algorithm'),
                details.get('nonce'), details.get('nc'), details.get('cnonce'),
                details.get('qop'), self.factory.method, self.factory.url,
                None)

            if details.get('qop'):
                response = (
                    'Digest username="******", realm="%s", nonce="%s", uri="%s", '
                    'response=%s, algorithm=%s, cnonce="%s", qop=%s, nc=%s' % (
                        user,
                        details.get('realm'),
                        details.get('nonce'),
                        self.factory.url,
                        digest,
                        details.get('algorithm'),
                        details.get('cnonce'),
                        details.get('qop'),
                        details.get('nc'),
                    ))
            else:
                response = (
                    'Digest username="******", realm="%s", nonce="%s", uri="%s", '
                    'response=%s, algorithm=%s' % (
                        user,
                        details.get('realm'),
                        details.get('nonce'),
                        self.factory.url,
                        digest,
                        details.get('algorithm'),
                    ))

            self.factory.headers['Authorization'] = response

            if self.factory.scheme == 'https':
                connect(
                    GAIEndpoint(reactor, self.factory.host, self.factory.port,
                                ssl.ClientContextFactory()), self.factory)
            else:
                connect(
                    GAIEndpoint(reactor, self.factory.host, self.factory.port),
                    self.factory)
            # self.log.debug("Retrying with digest after 401")

            return self.factory.deferred

        elif basicAvailable:
            basicauth = "%s:%s" % (user, pswd)
            basicauth = "Basic " + base64.encodestring(basicauth)
            basicauth = basicauth.replace("\n", "")

            self.factory.headers['Authorization'] = basicauth

            if self.factory.scheme == 'https':
                connect(
                    GAIEndpoint(reactor, self.factory.host, self.factory.port,
                                ssl.ClientContextFactory()), self.factory)
            else:
                connect(
                    GAIEndpoint(reactor, self.factory.host, self.factory.port),
                    self.factory)
            # self.log.debug("Retrying with basic after 401")

            return self.factory.deferred

        else:
            self.factory.deferred.errback(
                failure.Failure(
                    Unauthorized(
                        "Mail gateway not able to process reply; calendar server returned 401 and doesn't support basic or digest"
                    )))
            return self.factory.deferred
Ejemplo n.º 17
0
 def setUp(self):
     self.factory = RecordingClientFactory()
     self.endpoint = RecordingEndpoint()
     self.connector = connect(self.endpoint, self.factory)