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
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
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 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 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 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 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 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 _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
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
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
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
def setUp(self): self.factory = RecordingClientFactory() self.endpoint = RecordingEndpoint() self.connector = connect(self.endpoint, self.factory)
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