Ejemplo n.º 1
0
    def _processRequest(self):
        """
        Process the request by sending it to the relevant server.

        @return: the HTTP response.
        @rtype: L{Response}
        """
        ssl, host, port, _ignore_path = self.server.details()
        path = "/" + config.Servers.ConduitName

        headers = Headers()
        headers.setHeader("Host", utf8String(host + ":{}".format(port)))
        if self.streamType:
            # For attachments we put the base64-encoded JSON data into a header
            headers.setHeader("Content-Type", self.streamType)
            headers.addRawHeader("XPOD", base64.b64encode(self.data))
        else:
            headers.setHeader("Content-Type", MimeType("application", "json", params={"charset": "utf-8", }))
        headers.setHeader("User-Agent", "CalendarServer/{}".format(version))
        headers.addRawHeader(*self.server.secretHeader())

        from twisted.internet import reactor
        f = Factory()
        f.protocol = HTTPClientProtocol
        ep = GAIEndpoint(reactor, host, port, _configuredClientContextFactory() if ssl else None)
        proto = (yield ep.connect(f))

        request = ClientRequest("POST", path, headers, self.stream if self.stream is not None else self.data)

        if accountingEnabledForCategory("xPod"):
            self.loggedRequest = yield self.logRequest(request)

        response = (yield proto.submitRequest(request))

        returnValue(response)
Ejemplo n.º 2
0
    def __init__(self, store, directory, settings, reactor=None):
        self.store = store
        self.settings = settings
        if reactor is None:
            from twisted.internet import reactor
        self.reactor = reactor

        # If we're using our dedicated account on our local server, we're free
        # to delete all messages that arrive in the inbox so as to not let
        # cruft build up
        self.deleteAllMail = shouldDeleteAllMail(config.ServerHostName,
                                                 settings.Server,
                                                 settings.Username)
        self.mailReceiver = MailReceiver(store, directory)
        mailType = settings['Type']
        if mailType.lower().startswith('pop'):
            self.factory = POP3DownloadFactory
        else:
            self.factory = IMAP4DownloadFactory

        contextFactory = None
        if settings["UseSSL"]:
            contextFactory = ssl.ClientContextFactory()
        self.point = GAIEndpoint(self.reactor,
                                 settings.Server,
                                 settings.Port,
                                 contextFactory=contextFactory)
Ejemplo n.º 3
0
def installPool(name, url, maxClients=5, reactor=None):

    if reactor is None:
        from twisted.internet import reactor
    parsedURL = urlparse.urlparse(url)
    ctxf = _configuredClientContextFactory()
    pool = HTTPClientPool(
        name,
        parsedURL.scheme,
        GAIEndpoint(reactor, parsedURL.hostname, parsedURL.port),
        GAIEndpoint(reactor, parsedURL.hostname, parsedURL.port, ctxf),
        maxClients,
        reactor,
    )
    _clientPools[name] = pool
Ejemplo n.º 4
0
    def __init__(self, store, directory, settings, reactor=None):
        self.store = store
        self.settings = settings
        if reactor is None:
            from twisted.internet import reactor
        self.reactor = reactor

        # If we're using our dedicated account on our local server, we're free
        # to delete all messages that arrive in the inbox so as to not let
        # cruft build up
        self.deleteAllMail = shouldDeleteAllMail(
            config.ServerHostName,
            settings.Server, settings.Username)
        self.mailReceiver = MailReceiver(store, directory)
        mailType = settings['Type']
        if mailType.lower().startswith('pop'):
            self.factory = POP3DownloadFactory
        else:
            self.factory = IMAP4DownloadFactory

        contextFactory = None
        if settings["UseSSL"]:
            contextFactory = ssl.ClientContextFactory()
        self.point = GAIEndpoint(
            self.reactor, settings.Server,
            settings.Port, contextFactory=contextFactory)
Ejemplo n.º 5
0
class MailRetriever(service.Service):

    def __init__(self, store, directory, settings, reactor=None):
        self.store = store
        self.settings = settings
        if reactor is None:
            from twisted.internet import reactor
        self.reactor = reactor

        self.mailReceiver = MailReceiver(store, directory)
        mailType = settings['Type']
        if mailType.lower().startswith('pop'):
            self.factory = POP3DownloadFactory
        else:
            self.factory = IMAP4DownloadFactory

        contextFactory = None
        if settings["UseSSL"]:
            contextFactory = ssl.ClientContextFactory()
        self.point = GAIEndpoint(self.reactor, settings.Server,
            settings.Port, contextFactory=contextFactory)


    def fetchMail(self):
        return self.point.connect(self.factory(self.settings, self.mailReceiver))


    @inlineCallbacks
    def scheduleNextPoll(self, seconds=None):
        if seconds is None:
            seconds = self.settings["PollingSeconds"]
        yield scheduleNextMailPoll(self.store, seconds)
Ejemplo n.º 6
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.º 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 _processRequest(self):
        """
        Process the request by sending it to the relevant server.

        @return: the HTTP response.
        @rtype: L{Response}
        """
        ssl, host, port, _ignore_path = self.server.details()
        path = "/" + config.Servers.ConduitName

        headers = Headers()
        headers.setHeader("Host", utf8String(host + ":{}".format(port)))
        if self.streamType:
            # For attachments we put the base64-encoded JSON data into a header
            headers.setHeader("Content-Type", self.streamType)
            headers.addRawHeader("XPOD", base64.b64encode(self.data))
        else:
            headers.setHeader(
                "Content-Type",
                MimeType("application", "json", params={
                    "charset": "utf-8",
                }))
        headers.setHeader("User-Agent", "CalendarServer/{}".format(version))
        headers.addRawHeader(*self.server.secretHeader())

        from twisted.internet import reactor
        f = Factory()
        f.protocol = HTTPClientProtocol
        ep = GAIEndpoint(
            reactor, host, port,
            _configuredClientContextFactory(host) if ssl else None)
        proto = (yield ep.connect(f))

        request = ClientRequest(
            "POST", path, headers,
            self.stream if self.stream is not None else self.data)

        if accountingEnabledForCategory("xPod"):
            self.loggedRequest = yield self.logRequest(request)

        response = (yield proto.submitRequest(request))

        returnValue(response)
Ejemplo n.º 9
0
def installPools(pools, maxClients=5, reactor=None):
    if reactor is None:
        from twisted.internet import reactor
    for name, pool in pools.items():
        if pool["ClientEnabled"]:
            _installPool(
                name,
                pool["HandleCacheTypes"],
                GAIEndpoint(reactor, pool["BindAddress"], pool["Port"]),
                maxClients,
                reactor,
            )
Ejemplo n.º 10
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.º 11
0
def installPools(pools, maxClients=5, reactor=None):
    if reactor is None:
        from twisted.internet import reactor
    for name, pool in pools.items():
        if pool["ClientEnabled"]:
            if pool.get("MemcacheSocket"):
                ep = UNIXClientEndpoint(reactor, pool["MemcacheSocket"])
            else:
                ep = GAIEndpoint(reactor, pool["BindAddress"], pool["Port"])

            _installPool(
                name,
                pool["HandleCacheTypes"],
                ep,
                maxClients,
                reactor,
            )
Ejemplo n.º 12
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.º 13
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.º 14
0
    def __init__(self, store, directory, settings, reactor=None):
        self.store = store
        self.settings = settings
        if reactor is None:
            from twisted.internet import reactor
        self.reactor = reactor

        self.mailReceiver = MailReceiver(store, directory)
        mailType = settings['Type']
        if mailType.lower().startswith('pop'):
            self.factory = POP3DownloadFactory
        else:
            self.factory = IMAP4DownloadFactory

        contextFactory = None
        if settings["UseSSL"]:
            contextFactory = ssl.ClientContextFactory()
        self.point = GAIEndpoint(self.reactor, settings.Server,
            settings.Port, contextFactory=contextFactory)
Ejemplo n.º 15
0
class MailRetriever(service.Service):

    def __init__(self, store, directory, settings, reactor=None):
        self.store = store
        self.settings = settings
        if reactor is None:
            from twisted.internet import reactor
        self.reactor = reactor

        # If we're using our dedicated account on our local server, we're free
        # to delete all messages that arrive in the inbox so as to not let
        # cruft build up
        self.deleteAllMail = shouldDeleteAllMail(
            config.ServerHostName,
            settings.Server, settings.Username)
        self.mailReceiver = MailReceiver(store, directory)
        mailType = settings['Type']
        if mailType.lower().startswith('pop'):
            self.factory = POP3DownloadFactory
        else:
            self.factory = IMAP4DownloadFactory

        contextFactory = None
        if settings["UseSSL"]:
            contextFactory = ssl.ClientContextFactory()
        self.point = GAIEndpoint(
            self.reactor, settings.Server,
            settings.Port, contextFactory=contextFactory)


    def fetchMail(self):
        return self.point.connect(self.factory(
            self.settings, self.mailReceiver,
            self.deleteAllMail))


    @inlineCallbacks
    def scheduleNextPoll(self, seconds=None):
        if seconds is None:
            seconds = self.settings["PollingSeconds"]
        yield IMIPPollingWork.reschedule(self.store, seconds)
Ejemplo n.º 16
0
class MailRetriever(service.Service):
    def __init__(self, store, directory, settings, reactor=None):
        self.store = store
        self.settings = settings
        if reactor is None:
            from twisted.internet import reactor
        self.reactor = reactor

        # If we're using our dedicated account on our local server, we're free
        # to delete all messages that arrive in the inbox so as to not let
        # cruft build up
        self.deleteAllMail = shouldDeleteAllMail(config.ServerHostName,
                                                 settings.Server,
                                                 settings.Username)
        self.mailReceiver = MailReceiver(store, directory)
        mailType = settings['Type']
        if mailType.lower().startswith('pop'):
            self.factory = POP3DownloadFactory
        else:
            self.factory = IMAP4DownloadFactory

        contextFactory = None
        if settings["UseSSL"]:
            contextFactory = ssl.ClientContextFactory()
        self.point = GAIEndpoint(self.reactor,
                                 settings.Server,
                                 settings.Port,
                                 contextFactory=contextFactory)

    def fetchMail(self):
        return self.point.connect(
            self.factory(self.settings, self.mailReceiver, self.deleteAllMail))

    @inlineCallbacks
    def scheduleNextPoll(self, seconds=None):
        if seconds is None:
            seconds = self.settings["PollingSeconds"]
        yield IMIPPollingWork.reschedule(self.store, seconds)
Ejemplo n.º 17
0
 def makeEndpoint(self, host="abcd.example.com", port=4321):
     gaie = GAIEndpoint(self.clock, host, port)
     gaie.subEndpoint = self.subEndpoint
     gaie.deferToThread = self.deferToSomething
     return gaie
Ejemplo n.º 18
0
 def makeEndpoint(self, host="abcd.example.com", port=4321):
     gaie = GAIEndpoint(self.clock, host, port)
     gaie.subEndpoint = self.subEndpoint
     gaie.deferToThread = self.deferToSomething
     return gaie
Ejemplo n.º 19
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