def validateTo(self, user): recipient = str(user.dest) valid = yield self.isRecipientValid(recipient) if not valid: raise SMTPBadRcpt(user) swift_filesystem = SwiftFileSystem(self.swift_connection) path = '/smtp/%s/%s' % (recipient, uuid4()) d, swift_file = swift_filesystem.startFileUpload(path) message = SwiftMessage(d, swift_file) @defer.inlineCallbacks def onUpload(ignored): if not self.rabbitmq_cluster or not self.queue_name: defer.returnValue(None) replica = yield self.rabbitmq_cluster.connect() yield replica.send(self.queue_name, json.dumps({ 'username': self.swift_connection.username, 'path': path, 'origin': self.origin, 'recipient': recipient, 'subj': message.subject, 'gate': 'smtp'})) d.addCallback(onUpload) yield swift_file.started msg("Uploading %s" % path) defer.returnValue(lambda: message)
def on_declare(queue): msg("Queue %s declared" % queue_name) def on_publish_failed(result): channel, response, props, body = result msg("Publish failed %s" % response) self.channel.add_on_return_callback(on_publish_failed) yield self.channel.basic_publish(exchange='', body=body, routing_key=queue_name, properties=properties, mandatory=True)
def validateTo(self, user): recipient = str(user.dest) valid = yield self.isRecipientValid(recipient) if not valid: raise SMTPBadRcpt(user) swift_filesystem = SwiftFileSystem(self.swift_connection) path = '/smtp/%s/%s' % (recipient, uuid4()) d, swift_file = swift_filesystem.startFileUpload(path) message = SwiftMessage(d, swift_file) @defer.inlineCallbacks def onUpload(ignored): if not self.rabbitmq_cluster or not self.queue_name: defer.returnValue(None) replica = yield self.rabbitmq_cluster.connect() yield replica.send( self.queue_name, json.dumps({ 'username': self.swift_connection.username, 'path': path, 'origin': self.origin, 'recipient': recipient, 'subj': message.subject, 'gate': 'smtp' })) d.addCallback(onUpload) yield swift_file.started msg("Uploading %s" % path) defer.returnValue(lambda: message)
def send(self, queue_name, body): msg('Publishing %s body to "%s" on %s' % (len(body), queue_name, self)) properties = BasicProperties(delivery_mode=1) @defer.inlineCallbacks def on_declare(queue): msg("Queue %s declared" % queue_name) def on_publish_failed(result): channel, response, props, body = result msg("Publish failed %s" % response) self.channel.add_on_return_callback(on_publish_failed) yield self.channel.basic_publish(exchange='', body=body, routing_key=queue_name, properties=properties, mandatory=True) def on_declare_fail(error): msg('Can not declare queue %s' % error) d = self.channel.queue_declare(queue=queue_name, auto_delete=False, exclusive=False) d.addCallbacks(on_declare, on_declare_fail) return d
def ftp_AUTH(self, *args, **kwargs): mode, = args if mode == 'TLS': msg("Initiated TLS") self.reply(AUTH_OK) self.transport.startTLS(self.factory.cert_options) return return defer.fail(CmdNotImplementedError('AUTH %s' % mode))
def disconnect(self): msg('Disconnecting from %s' % self) if self.is_connected(): self.connection.close() d = defer.Deferred() def _disconnected(*args): d.callback(None) self.connection.add_on_close_callback(_disconnected) return d return defer.succeed(None)
def log_command(self, command, *args): """ Log command :param str command: Name of the command :param \*args args: Arguments passed into the command to be logged """ arg_list = ', '.join(str(arg) for arg in args) msg("cmd.%s(%s)" % (command, arg_list), system="SwFTP-SFTP, (%s)" % self.swiftconn.username, metric='command.%s' % command)
def connect(self, reconnect_after = None): replica = self.replicas[self.index] while not (yield replica.connect(self.credentials)): self.__next() replica = self.replicas[self.index] if self.index == 0: if reconnect_after: msg('Reconnecting afer %s sec' % reconnect_after) yield task.deferLater(reactor, reconnect_after, lambda: None) else: raise Exception("Rabbitmq cluster connection failed") defer.returnValue(replica)
def connect(self, reconnect_after=None): replica = self.replicas[self.index] while not (yield replica.connect(self.credentials)): self.__next() replica = self.replicas[self.index] if self.index == 0: if reconnect_after: msg('Reconnecting afer %s sec' % reconnect_after) yield task.deferLater(reactor, reconnect_after, lambda: None) else: raise Exception("Rabbitmq cluster connection failed") defer.returnValue(replica)
def connectionLost(self, *args, **kwargs): log.msg(metric='num_clients', count=-1) if self.shell: username = self.shell.username() msg("User Disconnected (%s) [%s/%s]" % ( username, self._connCountMap[username], self.maxConnectionsPerUser, )) self._connCountMap[username] -= 1 # To avoid a slow memory leak if self._connCountMap[username] == 0: del self._connCountMap[username] return super(SwftpFTPProtocol, self).connectionLost(*args, **kwargs)
def isRecipientValid(self, recipient): valid = self.recipients.get(recipient) if valid is not None: msg("Recipient %s is %svalid [cached]" % (recipient, "" if valid else "not ")) defer.returnValue(valid) if not self.swift_connection: self.swift_connection = yield self.connectToSwift() swift_filesystem = SwiftFileSystem(self.swift_connection) try: yield swift_filesystem.getAttrs(''.join(['/smtp/',recipient])) valid = True except swift.NotFound: valid = False msg("Recipient %s is %svalid" % (recipient, "" if valid else "not ")) self.recipients[recipient] = valid defer.returnValue(valid)
def isRecipientValid(self, recipient): valid = self.recipients.get(recipient) if valid is not None: msg("Recipient %s is %svalid [cached]" % (recipient, "" if valid else "not ")) defer.returnValue(valid) if not self.swift_connection: self.swift_connection = yield self.connectToSwift() swift_filesystem = SwiftFileSystem(self.swift_connection) try: yield swift_filesystem.getAttrs(''.join(['/smtp/', recipient])) valid = True except swift.NotFound: valid = False msg("Recipient %s is %svalid" % (recipient, "" if valid else "not ")) self.recipients[recipient] = valid defer.returnValue(valid)
def pass_cb(res): username = self.shell.username() self._connCountMap[username] += 1 msg("User Connected (%s) [%s/%s]" % ( username, self._connCountMap[username], self.maxConnectionsPerUser, )) if self.maxConnectionsPerUser != 0 and \ self._connCountMap[username] > self.maxConnectionsPerUser: msg("Too Many Connections For User (%s) [%s/%s]" % ( username, self._connCountMap[username], self.maxConnectionsPerUser, )) self.sendLine(RESPONSE[TOO_MANY_CONNECTIONS]) self.transport.loseConnection() return res
def connectionLost(self, reason): log.msg(metric='num_clients', count=-1) if getattr(self, 'avatar', None): username = self.avatar.username() msg("User Disconnected (%s) [%s/%s]" % ( username, self._connCountMap[username], self.maxConnectionsPerUser, )) self._connCountMap[username] -= 1 # To avoid a slow memory leak if self._connCountMap[username] == 0: del self._connCountMap[username] if self.service: self.service.serviceStopped() if hasattr(self, 'avatar'): self.logoutFunction()
def send(self, queue_name, body): msg('Publishing %s body to "%s" on %s' % (len(body), queue_name, self)) properties=BasicProperties(delivery_mode=1) @defer.inlineCallbacks def on_declare(queue): msg("Queue %s declared" % queue_name) def on_publish_failed(result): channel, response, props, body = result msg("Publish failed %s" % response) self.channel.add_on_return_callback(on_publish_failed) yield self.channel.basic_publish(exchange='', body=body, routing_key=queue_name, properties=properties, mandatory=True) def on_declare_fail(error): msg('Can not declare queue %s' % error) d = self.channel.queue_declare(queue=queue_name, auto_delete=False, exclusive=False) d.addCallbacks(on_declare, on_declare_fail) return d
def connect(self, credentials): if self.is_connected(): return defer.succeed(True) msg('Connecting to %s' % self) parameters = ConnectionParameters(virtual_host='/', credentials=credentials) cc = protocol.ClientCreator(reactor, TwistedProtocolConnection, parameters) d = cc.connectTCP(self.host, self.port, timeout=5) @defer.inlineCallbacks def success(connection): self.connection = connection self.channel = yield connection.channel() msg('Connected to %s channel open' % self) defer.returnValue(True) def failed(error): msg('Connect to %s failed: %s' % (self, error)) d.addCallback(lambda protocol: protocol.ready) d.addCallbacks(success, failed) return d
def on_auth(self, res): if not getattr(self, 'avatar', None): return res username = self.avatar.username() self._connCountMap[username] += 1 msg("User Connected (%s) [%s/%s]" % ( username, self._connCountMap[username], self.maxConnectionsPerUser, )) if self.maxConnectionsPerUser != 0 and \ self._connCountMap[username] > self.maxConnectionsPerUser: msg("Too Many Connections For User (%s) [%s/%s]" % ( username, self._connCountMap[username], self.maxConnectionsPerUser, )) self.sendDisconnect(DISCONNECT_TOO_MANY_CONNECTIONS, 'too many connections') self.loseConnection() return res
def on_auth(self, res): if not getattr(self, 'avatar', None): return res username = self.avatar.username() self._connCountMap[username] += 1 msg("User Connected (%s) [%s/%s]" % ( username, self._connCountMap[username], self.maxConnectionsPerUser, )) if self.maxConnectionsPerUser != 0 and \ self._connCountMap[username] > self.maxConnectionsPerUser: msg("Too Many Connections For User (%s) [%s/%s]" % ( username, self._connCountMap[username], self.maxConnectionsPerUser, )) self.sendDisconnect( DISCONNECT_TOO_MANY_CONNECTIONS, 'too many connections') self.loseConnection() return res
def success(connection): self.connection = connection self.channel = yield connection.channel() msg('Connected to %s channel open' % self) defer.returnValue(True)
def on_declare_fail(error): msg('Can not declare queue %s' % error)
def readLink(self, path): """ No-Op """ msg("NotImplemented try of readLink: path: [%s]" % str(path)) raise NotImplementedError
def makeLink(self, linkPath, targetPath): """ No-Op """ msg("NotImplemented try of makeLink: linkPath: [%s], targetPath: [%s]" % (str(linkPath), str(targetPath))) raise NotImplementedError
def on_publish_failed(result): channel, response, props, body = result msg("Publish failed %s" % response)
def extendedRequest(self, extName, extData): """ No-op """ msg("NotImplemented try of extendedRequest: extName: [%s], extData: [%s]" % (str(extName), str(extData))) raise NotImplementedError
def failed(error): msg('Connect to %s failed: %s' % (self, error))
def log_command(self, command, *args): arg_list = ', '.join(str(arg) for arg in args) msg("cmd: %s(%s)" % (command, arg_list), system="SwFTP-FTP, (%s)" % self.swiftconn.username, metric='command.%s' % command)
def setAttrs(self, path, attrs): """ Set attributes on a container/object. No-Op """ msg("NotImplemented try of setAttrs: path: [%s], attr: [%s]" % (str(path), str(attrs))) return