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)
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 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
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)
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)
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)
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
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)
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, )
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
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, )
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)
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
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)
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)
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)
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
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
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