示例#1
0
    def connect(self):
        application = service.Application('UniblabXMPP')

        xmppclient = XMPPClient(jid.internJID(self.xmpp_user), self.xmpp_pass)
        self.client=UniblabXMPPProtocol()
        self.client.transport = self
        self.client.setHandlerParent(xmppclient)
        xmppclient.setServiceParent(application)

        xmppclient.startService()
示例#2
0
class StatusProxy(object):
    def __init__(self, username, password, host='talk.google.com'):
        self.client = XMPPClient(JID(username), password,host)
        self.presence = PresenceFetcher()
        self.presence.setHandlerParent(self.client)
        self.client.startService()

    def getStatuses(self, account):
        if isinstance(account, str):
            account = JID(account)
        return self.presence.doProbe(account)
示例#3
0
    def __init__(self, myjid, mysecret):

        application = service.Application("Xmpp XiVO CTI")

        xmppclient = XMPPClient(jid.internJID(myjid), mysecret)
        xmppclient.setServiceParent(application)
        xmppclient.startService()
        xmppclient.logTraffic = DEBUG

        self.factory = xmppProtocol()
        self.factory.setHandlerParent(xmppclient)

        self.pubsub_factory = ctiPubSubClient(CONFIG["xmpp"]["jid"])
        self.pubsub_factory.setHandlerParent(xmppclient)
示例#4
0
文件: app.py 项目: pferreir/commitbot
def start_services(config):
    client = XMPPClient(jid.internJID(config.credentials['jid']), config.credentials['password'])

    application = service.Application('commitbot')

    bot = CommitBot(config)
    bot.setHandlerParent(client)

    site = server.Site(WebHook(config, bot))
    tcp_server = reactor.listenTCP(8888, site)

    app.startApplication(application, None)
    client.startService()

    reactor.run()
示例#5
0
文件: xmpp.py 项目: nutim/cowrie
class Output(cowrie.core.output.Output):

    def __init__(self):
        cowrie.core.output.Output.__init__(self)

    def start(self):
        from random import choice
        import string

        server = CONFIG.get('output_xmpp', 'server')
        user = CONFIG.get('output_xmpp', 'user')
        password = CONFIG.get('output_xmpp', 'password')
        muc = CONFIG.get('output_xmpp', 'muc')
        resource = ''.join([choice(string.ascii_letters)
                            for i in range(8)])
        jid = user + '/' + resource
        application = service.Application('honeypot')
        self.run(application, jid, password, JID(None, [muc, server, None]), server)

    def run(self, application, jidstr, password, muc, server):

        self.xmppclient = XMPPClient(JID(jidstr), password)
        if CONFIG.has_option('output_xmpp', 'debug') and \
                CONFIG.getboolean('output_xmpp', 'debug') is True:
            self.xmppclient.logTraffic = True  # DEBUG HERE
        (user, host, resource) = jid.parse(jidstr)
        self.muc = XMPPLoggerProtocol(
            muc, server, user + '-' + resource)
        self.muc.setHandlerParent(self.xmppclient)
        self.xmppclient.setServiceParent(application)
        self.anonymous = True
        self.xmppclient.startService()

    def write(self, logentry):
        for i in list(logentry.keys()):
            # Remove twisted 15 legacy keys
            if i.startswith('log_'):
                del logentry[i]
            elif i == "time":
                del logentry[i]
        msgJson = json.dumps(logentry, indent=5)

        self.muc.groupChat(self.muc.jrooms, msgJson)

    def stop(self):
        self.xmppclient.stopService()
示例#6
0
    def createXMPPClients(self, jid, password):
        """
        Create XMPP clients.

        @return: C{(xmppClient, pubsubClient)}
        """
        xmppClient = XMPPClient(jid, password)
        xmppClient.startService()

        presence = PresenceClientProtocol()
        presence.setHandlerParent(xmppClient)
        presence.available(priority=127)

        pubsubClient = SuperfeedrClient(self)
        pubsubClient.setHandlerParent(xmppClient)

        return xmppClient, pubsubClient
示例#7
0
class Output(cowrie.core.output.Output):

    def __init__(self):
        cowrie.core.output.Output.__init__(self)

    def start(self):
        from random import choice
        import string

        server = CONFIG.get('output_xmpp', 'server')
        user = CONFIG.get('output_xmpp', 'user')
        password = CONFIG.get('output_xmpp', 'password')
        muc = CONFIG.get('output_xmpp', 'muc')
        resource = ''.join([choice(string.ascii_letters)
                            for i in range(8)])
        jid = user + '/' + resource
        application = service.Application('honeypot')
        self.run(application, jid, password, JID(None, [muc, server, None]), server)

    def run(self, application, jidstr, password, muc, server):

        self.xmppclient = XMPPClient(JID(jidstr), password)
        if CONFIG.has_option('output_xmpp', 'debug') and \
                CONFIG.getboolean('output_xmpp', 'debug') is True:
            self.xmppclient.logTraffic = True  # DEBUG HERE
        (user, host, resource) = jid.parse(jidstr)
        self.muc = XMPPLoggerProtocol(
            muc, server, user + '-' + resource)
        self.muc.setHandlerParent(self.xmppclient)
        self.xmppclient.setServiceParent(application)
        self.anonymous = True
        self.xmppclient.startService()

    def write(self, logentry):
        for i in list(logentry.keys()):
            # Remove twisted 15 legacy keys
            if i.startswith('log_'):
                del logentry[i]
            elif i == "time":
                del logentry[i]
        msgJson = json.dumps(logentry, indent=5)

        self.muc.groupChat(self.muc.jrooms, msgJson)

    def stop(self):
        self.xmppclient.stopService()
示例#8
0
class StatusBotService(service.Service):
    def __init__(self):
        self.client = XMPPClient(JID(config.JABBER_CLIENT_USER),
                                 config.JABBER_CLIENT_PASS,
                                 config.JABBER_CLIENT_HOST)
        self.presenceFetcher = PresenceFetcher()
        self.presenceFetcher.setHandlerParent(self.client)
        self.tweeter = Tweeter()
        self.loopingCall = LoopingCall(self.makeRequest)

    def startService(self):
        service.Service.startService(self)
        self.client.startService()
        self.loopingCall.start(config.REFRESH_INTERVAL_SECS)

    def stopService(self):
        service.Service.stopService(self)
        self.loopingCall.stop()
        self.client.stopService()

    def makeRequest(self):
        d = self.presenceFetcher.doProbe(config.JABBER_TARGET)
        d.addCallbacks(self._sendTweet, log.err)
        return d

    def _sendTweet(self, statuses):
        if not statuses:
            log.msg("No statuses received")
            return succeed(None)
        else:
            d = self.tweeter.tweet(statuses[0])
            d.addCallback(self._receiveTweetResponse)
            return d

    def _receiveTweetResponse(self, result):
        code, body = result
        # 403 is probably a duplicate tweet
        if code == 200:
            decoded = json.loads(body)
            log.msg("Tweeted new status: " + decoded['text'])
        elif code == 403:
            log.msg("Duplicate tweet, ignoring")
        else:
            log.err("Error tweeting {}: {}".format(code, body))
示例#9
0
文件: xmpp.py 项目: yp2800/cowrie
class Output(cowrie.core.output.Output):
    """
    xmpp output
    """
    def start(self):
        server = CowrieConfig.get("output_xmpp", "server")
        user = CowrieConfig.get("output_xmpp", "user")
        password = CowrieConfig.get("output_xmpp", "password")
        muc = CowrieConfig.get("output_xmpp", "muc")
        resource = "".join([choice(string.ascii_letters) for i in range(8)])
        jid = user + "/" + resource
        application = service.Application("honeypot")
        self.run(application, jid, password, JID(None, [muc, server, None]),
                 server)

    def run(self, application, jidstr, password, muc, server):
        self.xmppclient = XMPPClient(JID(jidstr), password)
        if CowrieConfig.getboolean("output_xmpp", "debug", fallback=False):
            self.xmppclient.logTraffic = True
        (user, host, resource) = jid.parse(jidstr)
        self.muc = XMPPLoggerProtocol(muc, server, user + "-" + resource)
        self.muc.setHandlerParent(self.xmppclient)
        self.xmppclient.setServiceParent(application)
        self.anonymous = True
        self.xmppclient.startService()

    def write(self, logentry):
        for i in list(logentry.keys()):
            # Remove twisted 15 legacy keys
            if i.startswith("log_"):
                del logentry[i]
            elif i == "time":
                del logentry[i]
        msgJson = json.dumps(logentry, indent=5)

        self.muc.groupChat(self.muc.jrooms, msgJson)

    def stop(self):
        self.xmppclient.stopService()
示例#10
0
from twisted.internet import reactor
from twisted.words.protocols.jabber.jid import JID
from wokkel.client import XMPPClient


from echo import Echo
from roster import Roster

with open('account', 'r') as f:
    account = f.readlines()

jid = JID(account[0].rstrip('\n'))
password = account[1].rstrip('\n')

client = XMPPClient(jid, password)

echo = Echo()
roster = Roster()

roster.setHandlerParent(client)
echo.setHandlerParent(client)

client.startService()
reactor.run()
示例#11
0
class DBLogger(dblog.DBLogger):
    def start(self, cfg):
        from random import choice
        import string

        server = cfg.get('database_xmpp', 'server')
        user = cfg.get('database_xmpp', 'user')
        password = cfg.get('database_xmpp', 'password')
        muc = cfg.get('database_xmpp', 'muc')
        channels = {}
        for i in ('createsession', 'connectionlost', 'loginfailed',
                  'loginsucceeded', 'command', 'clientversion'):
            x = cfg.get('database_xmpp', 'signal_' + i)
            if not x in channels:
                channels[x] = []
            channels[x].append(i)

        resource = ''.join([choice(string.ascii_letters) for i in range(8)])
        jid = user + '/' + resource
        application = service.Application('honeypot')
        self.run(application, jid, password, muc, channels)

    def run(self, application, jidstr, password, muc, channels, anon=True):
        self.xmppclient = XMPPClient(jid.JID(jidstr), password)
        if self.cfg.has_option('database_xmpp', 'debug') and \
                self.cfg.get('database_xmpp', 'debug') in ('1', 'true', 'yes'):
            self.xmppclient.logTraffic = True  # DEBUG HERE
        (user, host, resource) = jid.parse(jidstr)
        self.muc = XMPPLoggerProtocol(muc, channels.keys(),
                                      user + '-' + resource)
        self.muc.setHandlerParent(self.xmppclient)
        self.xmppclient.setServiceParent(application)
        self.signals = {}
        for channel in channels:
            for signal in channels[channel]:
                self.signals[signal] = channel
        self.anonymous = True
        self.xmppclient.startService()

    def broadcast(self, msgtype, msg):
        if msgtype in self.signals:
            self.report(msgtype,
                        '%s@%s' % (self.signals[msgtype], self.muc.server),
                        msg)

    def report(self, msgtype, to, xmsg):
        body = domish.Element((None, 'body'))
        body.addContent('\n')
        msg = domish.Element(
            ('http://github.com/micheloosterhof/cowrie', 'cowrie'))
        msg['type'] = msgtype
        msg.addChild(xmsg)
        body.addChild(msg)
        self.muc.groupChat(jid.JID(to), body)

    # We have to return an unique ID
    def createSession(self, peerIP, peerPort, hostIP, hostPort):
        session = uuid.uuid4().hex
        ses = domish.Element((None, 'session'))
        ses['session'] = session
        ses['remote_host'] = peerIP
        ses['remote_port'] = str(peerPort)
        if self.anonymous == True:
            ses['local_host'] = '127.0.0.1'
        else:
            ses['local_host'] = hostIP
        ses['local_port'] = str(hostPort)

        self.broadcast('createsession', ses)
        return session

    def handleTTYLogOpened(self, session, args):
        pass

    def handleConnectionLost(self, session, args):
        ses = domish.Element((None, 'session'))
        ses['session'] = session
        self.broadcast('connectionlost', ses)

    def handleLoginFailed(self, session, args):
        ses = domish.Element((None, 'credentials'))
        ses['session'] = session
        ses['username'] = args['username']
        ses['password'] = args['password']
        self.broadcast('loginfailed', ses)

    def handleLoginSucceeded(self, session, args):
        ses = domish.Element((None, 'credentials'))
        ses['session'] = session
        ses['username'] = args['username']
        ses['password'] = args['password']
        self.broadcast('loginsucceeded', ses)

    def handleCommand(self, session, args):
        ses = domish.Element((None, 'command'))
        ses['session'] = session
        ses['command'] = 'known'
        ses.addContent(args['input'])
        self.broadcast('command', ses)

    def handleUnknownCommand(self, session, args):
        ses = domish.Element((None, 'command'))
        ses['session'] = session
        ses['command'] = 'unknown'
        ses.addContent(args['input'])
        self.broadcast('command', ses)

    def handleInput(self, session, args):
        ses = domish.Element((None, 'input'))
        ses['session'] = session
        ses['realm'] = args['realm']
        ses.addContent(args['input'])
        self.broadcast('input', ses)

    def handleTerminalSize(self, session, args):
        pass

    def handleClientVersion(self, session, args):
        ses = domish.Element((None, 'version'))
        ses['session'] = session
        ses['version'] = args['version']
        self.broadcast('clientversion', ses)
示例#12
0
文件: xmpp.py 项目: Guff/cowrie
class DBLogger(dblog.DBLogger):
    def start(self, cfg):
        from random import choice
        import string

        server      = cfg.get('database_xmpp', 'server')
        user        = cfg.get('database_xmpp', 'user')
        password    = cfg.get('database_xmpp', 'password')
        muc         = cfg.get('database_xmpp', 'muc')
        channels = {}
        for i in ('createsession', 'connectionlost', 'loginfailed',
                  'loginsucceeded', 'command', 'clientversion'):
            x = cfg.get('database_xmpp', 'signal_' + i)
            if not x in channels:
                channels[x] = []
            channels[x].append(i)

        resource = ''.join([choice(string.ascii_letters)
            for i in range(8)])
        jid = user + '/' + resource
        application = service.Application('honeypot')
        self.run(application, jid, password, JID(None,[muc,server,None]), channels)

    def run(self, application, jidstr, password, muc, channels, anon=True):

        self.xmppclient = XMPPClient(JID(jidstr), password)
        if self.cfg.has_option('database_xmpp', 'debug') and \
                self.cfg.get('database_xmpp', 'debug') in ('1', 'true', 'yes'):
            self.xmppclient.logTraffic = True # DEBUG HERE
        (user, host, resource) = jid.parse(jidstr)
        self.muc = XMPPLoggerProtocol(
            muc, channels.keys(), user + '-' + resource)
        self.muc.setHandlerParent(self.xmppclient)
        self.xmppclient.setServiceParent(application)
        self.signals = {}
        for channel in channels:
            for signal in channels[channel]:
                self.signals[signal] = channel
        self.anonymous = True
        self.xmppclient.startService()

    def broadcast(self, msgtype, msg):
        if msgtype in self.signals:
            self.report(msgtype, '%s@%s' %
                (self.signals[msgtype], self.muc.server) , msg)

    def report(self, msgtype, to, xmsg):
        msg = {}
        msg['type'] = msgtype
        msg['message'] = xmsg
        msgJson = json.dumps(msg,indent=5)
        self.muc.groupChat(self.muc.jrooms, msgJson)

    # We have to return an unique ID
    def createSession(self, peerIP, peerPort, hostIP, hostPort):
        session = uuid.uuid4().hex
        ses = {}
        ses['session'] = session
        ses['remote_host'] = peerIP
        ses['remote_port'] = str(peerPort)
        if self.anonymous == True:
            ses['local_host'] = '127.0.0.1'
        else:
            ses['local_host'] = hostIP
        ses['local_port'] = str(hostPort)

        self.broadcast('createsession', ses)
        return session

    def handleTTYLogOpened(self, session, args):
        pass

    def handleConnectionLost(self, session, args):
        ses = {}
        ses['session'] = session
        self.broadcast('connectionlost', ses)

    def handleLoginFailed(self, session, args):
        ses = {}
        ses['session'] = session
        ses['username'] = args['username']
        ses['password'] = args['password']
        self.broadcast('loginfailed', ses)

    def handleLoginSucceeded(self, session, args):
        ses = {}
        ses['session'] = session
        ses['username'] = args['username']
        ses['password'] = args['password']
        self.broadcast('loginsucceeded', ses)

    def handleCommand(self, session, args):
        ses = {}
        ses['session'] = session
        ses['command'] = 'known'
        ses['input'] = args['input']
        self.broadcast('command', ses)

    def handleUnknownCommand(self, session, args):
        ses = {}
        ses['session'] = session
        ses['command'] = 'unknown'
        ses['input']  = args['input']
        self.broadcast('command', ses)

    def handleInput(self, session, args):
        ses = {}
        ses['session'] = session
        ses['realm'] = args['realm']
        ses['input'] = args['input']
        self.broadcast('input', ses)

    def handleTerminalSize(self, session, args):
        pass

    def handleClientVersion(self, session, args):
        ses = {}
        ses['session'] = session
        ses['version'] = args['version']
        self.broadcast('clientversion', ses)
示例#13
0
import sys
from twisted.python import log
from twisted.internet import reactor
from twisted.words.protocols.jabber.jid import JID
from wokkel.client import XMPPClient
from wokkel.xmppim import RosterClientProtocol


class RosterHandler(RosterClientProtocol):
    def gotRoster(self, roster):
        print 'Got roster:'
        for entity, item in roster.iteritems():
            print '  %r (%r)' % (entity, item.name or '')

    def connectionInitialized(self):
        RosterClientProtocol.connectionInitialized(self)
        d = self.getRoster()
        d.addCallback(self.gotRoster)
        d.addErrback(log.err)


USER_JID, PASSWORD = sys.argv[1:3]
client = XMPPClient(JID(USER_JID), PASSWORD)
roster = RosterHandler()
roster.setHandlerParent(client)

client.startService()
reactor.run()
示例#14
0
文件: xmpp.py 项目: xlcteam/brutal-ng
class XmppBackend(ProtocolBackend):
    protocol_name = 'xmpp'

    def configure(self, *args, **kwargs):
        # user args
        self.nick = kwargs.get('nick')
        # TODO: remove, make this just the bot name...
        self.room_nick = kwargs.get('room_nick')
        if self.room_nick is None:
            self.room_nick = self.nick

        self.log_traffic = kwargs.get('log_traffic', False)
        #TODO: remove localhost default, fail.
        self.server = kwargs.get('server', 'localhost')
        self.port = kwargs.get('port', XMPP_DEFAULT_PORT)
        self.use_ssl = kwargs.get('use_ssl', True)
        self.keepalive_freq = kwargs.get('keepalive_freq')  # defaults to None
        if type(self.keepalive_freq) not in (None, float):
            try:
                self.keepalive_freq = float(self.keepalive_freq)
            except Exception as e:
                self.log.error('invalid keepalive passed in, {0!r}: {1!r}'.format(self.keepalive_freq, e))
                self.keepalive_freq = None

        #TODO: have this default to botname @ .
        self.jabber_id = kwargs.get('jabber_id', self.nick + '@' + self.server)
        #self.room_jabber_id =  # do we need this for servers that act wonky? maybe.
        self.password = kwargs.get('password')

        self.rooms = kwargs.get('rooms')

        # allow users to define custom handlers? not now.
        #self.subprotocol_handlers = kwargs.get()

        # internal
        self.bot_jid = jid.internJID(self.jabber_id)

        # probably want to override client?
        self.client = XMPPClient(self.bot_jid, self.password, host=self.server)

        if self.log_traffic is True:
            self.client.logTraffic = True

    # def connect_handlers(self):
    #     for subprotocol in self.subprotocol_handlers:
    #         instance = subprotocol()
    #         instance.setHandlerParent(self.client)

    def connect(self, *args, **kwargs):
        #TODO: try moving this below
        self.client.startService()

        # setup handlers
        self.muc_handler = MucBot(self.rooms, self.room_nick, backend=self)
        self.muc_handler.setHandlerParent(self.client)

        self.privatechat_handler = PrivateChatBot(backend=self)
        self.privatechat_handler.setHandlerParent(self.client)

        self.presence = xmppim.PresenceClientProtocol()
        self.presence.setHandlerParent(self.client)
        self.presence.available()

        self.keepalive = ClientKeepalive(interval=self.keepalive_freq)
        self.keepalive.setHandlerParent(self.client)

    def handle_action(self, action):
        self.log.debug('XMPP ACTION : {0!r}'.format(action))

        if action.action_type != 'message':
            return

        body = str(action.meta.get('body'))
        if not body:
            return

        if not action.destination_rooms:
            return

        for room in action.destination_rooms:
            if action.scope == 'public':
                room_jid = jid.internJID(room)
                message = muc.GroupChat(recipient=room_jid, body=body)
                self.client.send(message.toElement())

            if action.scope == 'private':
                if room is not None:
                    msg = xmppim.Message(recipient=jid.internJID(room),
                                         sender=self.bot_jid,
                                         body=body)
                    self.client.send(msg.toElement())
示例#15
0
class DBLogger(dblog.DBLogger):
    def start(self):
        from random import choice
        import string

        server = CONFIG.get('database_xmpp', 'server')
        user = CONFIG.get('database_xmpp', 'user')
        password = CONFIG.get('database_xmpp', 'password')
        muc = CONFIG.get('database_xmpp', 'muc')
        channels = {}
        for i in ('createsession', 'connectionlost', 'loginfailed',
                  'loginsucceeded', 'command', 'clientversion'):
            x = CONFIG.get('database_xmpp', 'signal_' + i)
            if x not in channels:
                channels[x] = []
            channels[x].append(i)

        resource = ''.join([choice(string.ascii_letters) for i in range(8)])
        jid = user + '/' + resource
        application = service.Application('honeypot')
        self.run(application, jid, password, JID(None, [muc, server, None]),
                 channels)

    def run(self, application, jidstr, password, muc, channels, anon=True):
        self.xmppclient = XMPPClient(JID(jidstr), password)
        if CONFIG.has_option('database_xmpp', 'debug') and CONFIG.getboolean(
                'database_xmpp', 'debug'):
            self.xmppclient.logTraffic = True  # DEBUG HERE
        (user, host, resource) = jid.parse(jidstr)
        self.muc = XMPPLoggerProtocol(muc, list(channels.keys()),
                                      user + '-' + resource)
        self.muc.setHandlerParent(self.xmppclient)
        self.xmppclient.setServiceParent(application)
        self.signals = {}
        for channel in channels:
            for signal in channels[channel]:
                self.signals[signal] = channel
        self.anonymous = True
        self.xmppclient.startService()

    def broadcast(self, msgtype, msg):
        if msgtype in self.signals:
            self.report(msgtype, '{}@{}'.format(self.signals[msgtype],
                                                self.muc.server), msg)

    def report(self, msgtype, to, xmsg):
        msg = {}
        msg['type'] = msgtype
        msg['message'] = xmsg
        msgJson = json.dumps(msg, indent=5)
        self.muc.groupChat(self.muc.jrooms, msgJson)

    # We have to return an unique ID
    def createSession(self, peerIP, peerPort, hostIP, hostPort):
        session = uuid.uuid4().hex
        ses = {}
        ses['session'] = session
        ses['remote_host'] = peerIP
        ses['remote_port'] = str(peerPort)
        if self.anonymous:
            ses['local_host'] = '127.0.0.1'
        else:
            ses['local_host'] = hostIP
        ses['local_port'] = str(hostPort)

        self.broadcast('createsession', ses)
        return session

    def handleTTYLogOpened(self, session, args):
        pass

    def handleConnectionLost(self, session, args):
        ses = {}
        ses['session'] = session
        self.broadcast('connectionlost', ses)

    def handleLoginFailed(self, session, args):
        ses = {}
        ses['session'] = session
        ses['username'] = args['username']
        ses['password'] = args['password']
        self.broadcast('loginfailed', ses)

    def handleLoginSucceeded(self, session, args):
        ses = {}
        ses['session'] = session
        ses['username'] = args['username']
        ses['password'] = args['password']
        self.broadcast('loginsucceeded', ses)

    def handleCommand(self, session, args):
        ses = {}
        ses['session'] = session
        ses['command'] = 'known'
        ses['input'] = args['input']
        self.broadcast('command', ses)

    def handleUnknownCommand(self, session, args):
        ses = {}
        ses['session'] = session
        ses['command'] = 'unknown'
        ses['input'] = args['input']
        self.broadcast('command', ses)

    def handleInput(self, session, args):
        ses = {}
        ses['session'] = session
        ses['realm'] = args['realm']
        ses['input'] = args['input']
        self.broadcast('input', ses)

    def handleTerminalSize(self, session, args):
        pass

    def handleClientVersion(self, session, args):
        ses = {}
        ses['session'] = session
        ses['version'] = args['version']
        self.broadcast('clientversion', ses)
示例#16
0
class XmppBackend(ProtocolBackend):
    protocol_name = 'xmpp'

    def configure(self, *args, **kwargs):
        # user args
        self.nick = kwargs.get('nick')
        # TODO: remove, make this just the bot name...
        self.room_nick = kwargs.get('room_nick')
        if self.room_nick is None:
            self.room_nick = self.nick

        self.log_traffic = kwargs.get('log_traffic', False)
        #TODO: remove localhost default, fail.
        self.server = kwargs.get('server', 'localhost')
        self.port = kwargs.get('port', XMPP_DEFAULT_PORT)
        self.use_ssl = kwargs.get('use_ssl', True)
        self.keepalive_freq = kwargs.get('keepalive_freq')  # defaults to None
        if type(self.keepalive_freq) not in (None, float):
            try:
                self.keepalive_freq = float(self.keepalive_freq)
            except Exception as e:
                self.log.error(
                    'invalid keepalive passed in, {0!r}: {1!r}'.format(
                        self.keepalive_freq, e))
                self.keepalive_freq = None

        #TODO: have this default to botname @ .
        self.jabber_id = kwargs.get('jabber_id', self.nick + '@' + self.server)
        #self.room_jabber_id =  # do we need this for servers that act wonky? maybe.
        self.password = kwargs.get('password')

        self.rooms = kwargs.get('rooms')

        # allow users to define custom handlers? not now.
        #self.subprotocol_handlers = kwargs.get()

        # internal
        self.bot_jid = jid.internJID(self.jabber_id)

        # probably want to override client?
        self.client = XMPPClient(self.bot_jid, self.password, host=self.server)

        if self.log_traffic is True:
            self.client.logTraffic = True

    # def connect_handlers(self):
    #     for subprotocol in self.subprotocol_handlers:
    #         instance = subprotocol()
    #         instance.setHandlerParent(self.client)

    def connect(self, *args, **kwargs):
        #TODO: try moving this below
        self.client.startService()

        # setup handlers
        self.muc_handler = MucBot(self.rooms, self.room_nick, backend=self)
        self.muc_handler.setHandlerParent(self.client)

        self.presence = xmppim.PresenceClientProtocol()
        self.presence.setHandlerParent(self.client)
        self.presence.available()

        self.keepalive = ClientKeepalive(interval=self.keepalive_freq)
        self.keepalive.setHandlerParent(self.client)

    def handle_action(self, action):
        #self.log.debug(': {0!r}'.format(action))

        if action.action_type == 'message':
            body = action.meta.get('body')
            if body:
                if action.destination_rooms:
                    for room in action.destination_rooms:
                        if action.scope == 'public':
                            # TODO: replace this with an actual room lookup of known rooms
                            room_jid = jid.internJID(room)
                            message = muc.GroupChat(recipient=room_jid,
                                                    body=body)
                            self.client.send(message.toElement())