예제 #1
0
파일: server.py 프로젝트: pds0070/punjab
class IQAuthFeature(object):
    """ XEP-0078 : http://www.xmpp.org/extensions/xep-0078.html"""

    implements(IXMPPAuthenticationFeature)

    IQ_GET_AUTH = xpath.internQuery(ns.IQ_GET_AUTH)
    IQ_SET_AUTH = xpath.internQuery(ns.IQ_SET_AUTH)

    def associateWithStream(self, xs):
        """Add a streamm start event observer.
           And do other things to associate with the xmlstream if necessary.
        """
        self.xmlstream = xs
        self.xmlstream.addOnetimeObserver(xmlstream.STREAM_START_EVENT,
                                          self.streamStarted)

    def disassociateWithStream(self, xs):
        self.xmlstream.removeObserver(self.IQ_GET_AUTH, self.authRequested)
        self.xmlstream.removeObserver(self.IQ_SET_AUTH, self.auth)
        self.xmlstream = None

    def streamStarted(self, elm):
        """
        Called when client sends stream:stream
        """
        self.xmlstream.addObserver(self.IQ_GET_AUTH, self.authRequested)
        self.xmlstream.addObserver(self.IQ_SET_AUTH, self.auth)

    def authRequested(self, elem):
        """Return the supported auth type.

        """
        resp = domish.Element(('iq', ns.NS_CLIENT))
        resp['type'] = 'result'
        resp['id'] = elem['id']
        q = resp.addElement("query", ns.NS_AUTH)
        q.addElement("username", content=str(elem.query.username))
        q.addElement("digest")
        q.addElement("password")
        q.addElement("resource")

        self.xmlstream.send(resp)

    def auth(self, elem):
        """Do not auth the user, anyone can log in"""

        username = elem.query.username.__str__()
        resource = elem.query.resource.__str__()

        user = jid.internJID(username + '@' + self.xmlstream.host + '/' +
                             resource)

        resp = domish.Element(('iq', ns.NS_CLIENT))
        resp['type'] = 'result'
        resp['id'] = elem['id']

        self.xmlstream.send(resp)

        self.xmlstream.authenticated(user)
예제 #2
0
class JabberRouter(JabberComponent):

    routes = None

    # this is probably just a helper for the router
    # to speed things up if we already know where to go
    NAMED_ROUTE = xpath.internQuery("""/route""")

    def __init__(self, *args, **kw):
        JabberComponent.__init__(self, *args, **kw)
        self.bootstraps = [(self.NAMED_ROUTE, self.onNamedRoute)]
        #self.routes = []

    def startService(self):
        JabberComponent.startService(self)
        for event, fn in self.bootstraps:
            self.addObserver(event, fn)

    def onNamedRoute(self, elm):
        print "i know where to go"
        pass

    def onElement(self, elm):
        print "routing element", elm.toXml()
        JabberComponent.onElement(self, elm)
예제 #3
0
    def _getEventAndObservers(self, event):
        if isinstance(event, xpath.XPathQuery):
            # Treat as xpath
            observers = self._xpathObservers
        else:
            if self.prefix == event[:len(self.prefix)]:
                # Treat as event
                observers = self._eventObservers
            else:
                # Treat as xpath
                event = xpath.internQuery(event)
                observers = self._xpathObservers

        return event, observers
예제 #4
0
    def _getEventAndObservers(self, event):
        if isinstance(event, xpath.XPathQuery):
            # Treat as xpath
            observers = self._xpathObservers
        else:
            if self.prefix == event[:len(self.prefix)]:
                # Treat as event
                observers = self._eventObservers
            else:
                # Treat as xpath
                event = xpath.internQuery(event)
                observers = self._xpathObservers

        return event, observers
예제 #5
0
    def handleRequest(self, xml):
        """
        Find a handler and call it directly
        """
        handler = None
        iq = parseXml(xml)
        for queryString, method in self.service.iqHandlers.iteritems():
            if xpath.internQuery(queryString).matches(iq):
                handler = getattr(self.service, method)

        if handler:
            d = defer.maybeDeferred(handler, iq)
        else:
            d = defer.fail(NotImplementedError())

        return d
예제 #6
0
    def handleRequest(self, xml):
        """
        Find a handler and call it directly
        """
        handler = None
        iq = parseXml(xml)
        for queryString, method in self.service.iqHandlers.iteritems():
            if xpath.internQuery(queryString).matches(iq):
                handler = getattr(self.service, method)

        if handler:
            d = defer.maybeDeferred(handler, iq)
        else:
            d = defer.fail(NotImplementedError())

        return d
예제 #7
0
    def handleRequest(self, iq):
        """
        Find a handler and wrap the call for sending a response stanza.
        """
        def toResult(result, iq):
            response = toResponse(iq, 'result')

            if result:
                if IElement.providedBy(result):
                    response.addChild(result)
                else:
                    for element in result:
                        response.addChild(element)

            return response

        def checkNotImplemented(failure):
            failure.trap(NotImplementedError)
            raise error.StanzaError('feature-not-implemented')

        def fromStanzaError(failure, iq):
            failure.trap(error.StanzaError)
            return failure.value.toResponse(iq)

        def fromOtherError(failure, iq):
            log.msg("Unhandled error in iq handler:", isError=True)
            log.err(failure)
            return error.StanzaError('internal-server-error').toResponse(iq)

        handler = None
        for queryString, method in self.iqHandlers.iteritems():
            if xpath.internQuery(queryString).matches(iq):
                handler = getattr(self, method)

        if handler:
            d = defer.maybeDeferred(handler, iq)
        else:
            d = defer.fail(NotImplementedError())

        d.addCallback(toResult, iq)
        d.addErrback(checkNotImplemented)
        d.addErrback(fromStanzaError, iq)
        d.addErrback(fromOtherError, iq)

        d.addCallback(self.send)

        iq.handled = True
예제 #8
0
    def handleRequest(self, iq):
        """
        Find a handler and wrap the call for sending a response stanza.
        """
        def toResult(result, iq):
            response = toResponse(iq, 'result')

            if result:
                if IElement.providedBy(result):
                    response.addChild(result)
                else:
                    for element in result:
                        response.addChild(element)

            return response

        def checkNotImplemented(failure):
            failure.trap(NotImplementedError)
            raise error.StanzaError('feature-not-implemented')

        def fromStanzaError(failure, iq):
            e = failure.trap(error.StanzaError)
            return failure.value.toResponse(iq)

        def fromOtherError(failure, iq):
            log.msg("Unhandled error in iq handler:", isError=True)
            log.err(failure)
            return error.StanzaError('internal-server-error').toResponse(iq)

        handler = None
        for queryString, method in self.iqHandlers.iteritems():
            if xpath.internQuery(queryString).matches(iq):
                handler = getattr(self, method)

        if handler:
            d = defer.maybeDeferred(handler, iq)
        else:
            d = defer.fail(NotImplementedError())

        d.addCallback(toResult, iq)
        d.addErrback(checkNotImplemented)
        d.addErrback(fromStanzaError, iq)
        d.addErrback(fromOtherError, iq)

        d.addCallback(self.send)

        iq.handled = True
예제 #9
0
    def removeObserver(self, event, observerfn):
        """ Remove function as observer for an event.

        The observer function is removed for all priority levels for the
        specified event.
        
        @param event: Event for which the observer function was registered.
        @type event: L{str} or L{xpath.XPathQuery}
        @param observerfn: Observer function to be unregistered.
        """

        # If this is happening in the middle of the dispatch, queue
        # it up for processing after the dispatch completes
        if self._dispatchDepth > 0:
            self._updateQueue.append(
                lambda: self.removeObserver(event, observerfn))
            return

        observers = None

        if _isStr(event):
            if self.prefix == event[0:len(self.prefix)]:
                observers = self._eventObservers
            else:
                event = xpath.internQuery(event)
                observers = self._xpathObservers
        else:
            observers = self._xpathObservers

        for priority, query in observers:
            if event == query:
                observers[(priority, query)].removeCallback(observerfn)

        # Update the priority ordered list of xpath keys --
        # This really oughta be rethought for efficiency
        self._orderedEventObserverKeys = self._eventObservers.keys()
        self._orderedEventObserverKeys.sort()
        self._orderedEventObserverKeys.reverse()
        self._orderedXpathObserverKeys = self._xpathObservers.keys()
        self._orderedXpathObserverKeys.sort()
        self._orderedXpathObserverKeys.reverse()
예제 #10
0
    def handleRequest(self, xml):
        """
        Find a handler and call it directly.

        @param xml: XML stanza that may yield a handler being called.
        @type xml: C{str}.
        @return: Deferred that fires with the result of a handler for this
                 stanza. If no handler was found, the deferred has its errback
                 called with a C{NotImplementedError} exception.
        """
        handler = None
        iq = parseXml(xml)
        for queryString, method in iteritems(self.service.iqHandlers):
            if xpath.internQuery(queryString).matches(iq):
                handler = getattr(self.service, method)

        if handler:
            d = defer.maybeDeferred(handler, iq)
        else:
            d = defer.fail(NotImplementedError())

        return d
예제 #11
0
파일: helpers.py 프로젝트: ralphm/wokkel
    def handleRequest(self, xml):
        """
        Find a handler and call it directly.

        @param xml: XML stanza that may yield a handler being called.
        @type xml: C{str}.
        @return: Deferred that fires with the result of a handler for this
                 stanza. If no handler was found, the deferred has its errback
                 called with a C{NotImplementedError} exception.
        """
        handler = None
        iq = parseXml(xml)
        for queryString, method in iteritems(self.service.iqHandlers):
            if xpath.internQuery(queryString).matches(iq):
                handler = getattr(self.service, method)

        if handler:
            d = defer.maybeDeferred(handler, iq)
        else:
            d = defer.fail(NotImplementedError())

        return d
예제 #12
0
    def _addObserver(self, onetime, event, observerfn, priority, *args,
                     **kwargs):
        # If this is happening in the middle of the dispatch, queue
        # it up for processing after the dispatch completes
        if self._dispatchDepth > 0:
            self._updateQueue.append(lambda: self.addObserver(
                event, observerfn, priority, *args, **kwargs))
            return

        observers = None

        if _isStr(event):
            if self.prefix == event[0:len(self.prefix)]:
                # Treat as event
                observers = self._eventObservers
            else:
                # Treat as xpath
                event = xpath.internQuery(event)
                observers = self._xpathObservers
        else:
            # Treat as xpath
            observers = self._xpathObservers

        key = (priority, event)
        if not key in observers:
            cbl = CallbackList()
            cbl.addCallback(onetime, observerfn, *args, **kwargs)
            observers[key] = cbl
        else:
            observers[key].addCallback(onetime, observerfn, *args, **kwargs)

        # Update the priority ordered list of xpath keys --
        # This really oughta be rethought for efficiency
        self._orderedEventObserverKeys = self._eventObservers.keys()
        self._orderedEventObserverKeys.sort()
        self._orderedEventObserverKeys.reverse()
        self._orderedXpathObserverKeys = self._xpathObservers.keys()
        self._orderedXpathObserverKeys.sort()
        self._orderedXpathObserverKeys.reverse()
예제 #13
0
import re
import htmlentitydefs

from twisted.web.client import getPage
from twisted.internet import reactor
from twisted.names.srvconnect import SRVConnector
from twisted.words.xish import domish, xpath
from twisted.words.protocols.jabber import xmlstream, client, jid
from twisted.python import log

import messenger
from rcore import config, scheduler
from hermes.contacts import Contact, AT_XMPP
from rcore.core import Core

MessageWithBody = xpath.internQuery("/message/body")
MessageWithError = xpath.internQuery("/message/error")

##
# Removes HTML or XML character references and entities from a text string.
#
# @param text The HTML (or XML) source text.
# @return The plain text, as a Unicode string, if necessary.


def unescape(text):
    def fixup(m):
        text = m.group(0)
        if text[:2] == "&#":
            # character reference
            try:
예제 #14
0
class JabberComponentProxy(JabberProtocol):
    namespace = NS_COMPONENT

    ROUTE_ADDED = xpath.internQuery("/iq/route/add")
    ROUTE_REMOVED = xpath.internQuery("/iq/route/remove")
    
    # this is the routing bits
    def _handle(self, elm):
        self.send(elm)

    def _onElement(self, elm):
        #print "routing to", self.parent
        self.factory.handle(elm)


    #def addObserver(self, event, observerfn, *args, **kw):
    #    print "add observer!", event, observerfn
    #    JabberProtocol.addObserver(self, event, observerfn, *args, **kw)

    def _addForwardingObserver(self, event, observerfn, 
                               priority=0, *args, **kw):
        JabberProtocol.addObserver(self, event, observerfn, 
                                        priority, *args, **kw)
        self.addRoute(event, priority)

    def _removeForwardingObserver(self, event, observerfn):
        raise NotImplementedError

    def addRoute(self, event, priority=0):
        iq = IQRequest("set")
        r = iq.addElement("route", NS_ROUTE)
        a = r.addElement("add")
        a.addElement("xpath", content=event.queryStr)
        a.addElement("priority", content=priority)
        d = iq.send(self)
        
        def success(elm):
            self.routes[event] = str(elm.route.id)

        d.addCallback(success)

    #inherited callbacks
    def streamAuthenticated(self, elm):
        JabberProtocol.streamAuthenticated(self, elm)
        self.addObserver(self.ROUTE_ADDED, self.routeAdded)
        self.addObserver(self.ROUTE_REMOVED, self.routeRemoved)
        # we are going to switch to the forwarding observer style now
        self.addObserver = self._addForwardingObserver
        self.removeObverser = self._removeForwardingObserver
        self.handle = self._handle
        self.onElement = self._onElement

    # callbacks
    def routeAdded(self, elm):
        # just xpath for now
        q = elm.route.add.xpath
        p = elm.route.add.priority
        id = elm.id

        # the callback will basically just be to send 
        # the data to the remote host
        self.parent.addObserver(q, self.send, p)

        # add this route to our store of routes
        self.routes[id] = q

        # respond to the reques
        # TODO

    def routeRemoved(self, elm):
        # just xpath for now
        id = elm.route.remove.id

        self.parent.removeObserver(self.routes[id], self.send)
예제 #15
0
파일: xmpp.py 프로젝트: Ri0n/Hermes
import re
import htmlentitydefs

from twisted.web.client import getPage
from twisted.internet import reactor
from twisted.names.srvconnect import SRVConnector
from twisted.words.xish import domish, xpath
from twisted.words.protocols.jabber import xmlstream, client, jid
from twisted.python import log

import messenger
from rcore import config, scheduler
from hermes.contacts import Contact, AT_XMPP
from rcore.core import Core

MessageWithBody = xpath.internQuery("/message/body")
MessageWithError = xpath.internQuery("/message/error")


##
# Removes HTML or XML character references and entities from a text string.
#
# @param text The HTML (or XML) source text.
# @return The plain text, as a Unicode string, if necessary.

def unescape(text):
    def fixup(m):
        text = m.group(0)
        if text[:2] == "&#":
            # character reference
            try:
예제 #16
0
# -*- test-case-name: twisted.words.test.test_jabberclient -*-
#
# Copyright (c) Twisted Matrix Laboratories.
# See LICENSE for details.

from twisted.words.xish import domish, xpath, utility
from twisted.words.protocols.jabber import xmlstream, sasl, error
from twisted.words.protocols.jabber.jid import JID

NS_XMPP_STREAMS = 'urn:ietf:params:xml:ns:xmpp-streams'
NS_XMPP_BIND = 'urn:ietf:params:xml:ns:xmpp-bind'
NS_XMPP_SESSION = 'urn:ietf:params:xml:ns:xmpp-session'
NS_IQ_AUTH_FEATURE = 'http://jabber.org/features/iq-auth'

DigestAuthQry = xpath.internQuery("/iq/query/digest")
PlaintextAuthQry = xpath.internQuery("/iq/query/password")


def basicClientFactory(jid, secret):
    a = BasicAuthenticator(jid, secret)
    return xmlstream.XmlStreamFactory(a)


class IQ(domish.Element):
    """
    Wrapper for a Info/Query packet.

    This provides the necessary functionality to send IQs and get notified when
    a result comes back. It's a subclass from L{domish.Element}, so you can use
    the standard DOM manipulation calls to add data to the outbound request.
예제 #17
0
# -*- test-case-name: twisted.words.test.test_jabberclient -*-
#
# Copyright (c) Twisted Matrix Laboratories.
# See LICENSE for details.

from twisted.words.xish import domish, xpath, utility
from twisted.words.protocols.jabber import xmlstream, sasl, error
from twisted.words.protocols.jabber.jid import JID

NS_XMPP_STREAMS = 'urn:ietf:params:xml:ns:xmpp-streams'
NS_XMPP_BIND = 'urn:ietf:params:xml:ns:xmpp-bind'
NS_XMPP_SESSION = 'urn:ietf:params:xml:ns:xmpp-session'
NS_IQ_AUTH_FEATURE = 'http://jabber.org/features/iq-auth'

DigestAuthQry = xpath.internQuery("/iq/query/digest")
PlaintextAuthQry = xpath.internQuery("/iq/query/password")

def basicClientFactory(jid, secret):
    a = BasicAuthenticator(jid, secret)
    return xmlstream.XmlStreamFactory(a)

class IQ(domish.Element):
    """
    Wrapper for a Info/Query packet.

    This provides the necessary functionality to send IQs and get notified when
    a result comes back. It's a subclass from L{domish.Element}, so you can use
    the standard DOM manipulation calls to add data to the outbound request.

    @type callbacks: L{utility.CallbackList}
    @cvar callbacks: Callback list to be notified when response comes back
예제 #18
0
class NonSASLAuthenticationFeature(object):
    """JEP-0078"""

    implements(IJabberAuthenticationFeature)

    feature = "some_feature_id"

    # event triggers
    AUTH_FIELDS_REQUESTED_EVENT = \
        xpath.internQuery("""/iq[@type="get"]/query[@xmlns="jabber:iq:auth"]""")
    AUTH_FIELDS_PROVIDED_EVENT = \
        xpath.internQuery("""/iq[@type="set"]/query[@xmlns="jabber:iq:auth"]""")

    def associateWithStream(self, xs):
        """do all the things necessary to register ourselves 
           with the xmlstream
        """
        self.xmlstream = xs
        self.xmlstream.addOnetimeObserver(xmlstream.STREAM_START_EVENT,
                                          self.streamStarted)

    def disassociateWithStream(self, xs):
        if not self.xmlstream.initiating:
            self.xmlstream.removeObserver(self.AUTH_FIELDS_REQUESTED_EVENT,
                                          self.authFieldsRequested)
            self.xmlstream.removeObserver(self.AUTH_FIELDS_PROVIDED_EVENT,
                                          self.authFieldsProvided)
        self.xmlstream = None

    #actions
    def authenticate(self):
        self.requestAuthFields()

    def checkSupported(self, *args):
        """return a deferred, callback with self on success, errback"""

    def requestAuthFields(self):
        #iq = IQRequest("get", to=self.xmlstream.otherHost
        pass

    def provideAuthFields(self):
        pass

    #callbacks
    def streamStarted(self, elm):
        if not self.xmlstream.initiating:
            self.xmlstream.addObserver(self.AUTH_FIELDS_REQUESTED_EVENT,
                                       self.authFieldsRequested)
            self.xmlstream.addObserver(self.AUTH_FIELDS_PROVIDED_EVENT,
                                       self.authFieldsProvided)

    def authFieldsRequested(self, elm):
        """return the types of auth fields that are supported"""

        print "auth fields requested!"
        resp = IQStanza(type="result", id=elm['id'])
        q = resp.addElement("query", "jabber:iq:auth")
        q.addElement("username", content=str(elm.query.username))
        q.addElement("digest")
        q.addElement("password")
        q.addElement("resource")

        self.xmlstream.send(resp)

    def authFieldsProvided(self, elm):
        """authenticate the user or return an error"""
        # XXX andy: theoretically this defers the actual authentication to
        #           the factory/service
        print "auth fields provided!"
        user = JabberUser(self.xmlstream.host, str(elm.query.username),
                          str(elm.query.resource))

        resp = IQStanza(type="result", id=elm['id'])
        self.xmlstream.send(resp)

        # XXX andy: for now I am just makign a user class,
        #           there is surely a better way to do this
        self.xmlstream.authenticated(user)
예제 #19
0
파일: serv.py 프로젝트: rjpatawaran/pretzel
class IMFeature(object):
    implements(IJabberFeature)
    feature = "blah"

    ROSTER_REQUESTED_EVENT = \
        xpath.internQuery("""/iq[@type="get"]/query[@xmlns="jabber:iq:roster"]""")

    def associateWithStream(self, xs):
        self.xmlstream = xs
        self.xmlstream.addObserver(self.ROSTER_REQUESTED_EVENT,
                                   self.rosterRequested)

    def rosterRequested(self, elm):
        #raise NotImplementedError
        print "roster requested!"
        #return
        id = elm['id']
        msg = """<iq from="%s" type="result" id="%s" >
            <query xmlns="jabber:iq:roster">
            <item subscription="from" jid="*****@*****.**" />
            <item subscription="to" jid="*****@*****.**" >
            <group>.be</group>
            </item>
            <item subscription="both" jid="*****@*****.**" >
            <group>sf</group>
            </item>
            <item subscription="both" jid="*****@*****.**" >
            <group>sf</group>
            </item>
            <item subscription="both" jid="*****@*****.**" >
            <group>.be</group>
            </item>
            <item ask="subscribe" subscription="none" jid="*****@*****.**" >
            <group>.de</group>
            </item>
            <item subscription="both" jid="*****@*****.**" >
            <group>.de</group>
            </item>
            <item subscription="both" jid="*****@*****.**" >
            <group>...</group>
            </item>
            <item subscription="both" jid="*****@*****.**" >
            <group>...</group>
            </item>
            <item subscription="both" jid="*****@*****.**" >
            <group>.nl</group>
            </item>
            <item subscription="both" jid="*****@*****.**" >
            <group>.nl</group>
            </item>
            <item subscription="both" jid="*****@*****.**" >
            <group>.nl</group>
            </item>
            <item subscription="both" jid="*****@*****.**" >
            <group>.nl</group>
            </item>
            <item subscription="both" jid="*****@*****.**" >
            <group>.nl</group>
            </item>
            </query>
            </iq>
        """%(str(self.xmlstream.user), id)
        self.xmlstream.send(msg)
예제 #20
0
class NonSASLAuthenticationFeature(object):
    """JEP-0078"""
    
    implements(IJabberAuthenticationFeature)
    
    feature = "some_feature_id"
    
    # event triggers
    AUTH_FIELDS_REQUESTED_EVENT = \
        xpath.internQuery("""/iq[@type="get"]/query[@xmlns="jabber:iq:auth"]""")
    AUTH_FIELDS_PROVIDED_EVENT = \
        xpath.internQuery("""/iq[@type="set"]/query[@xmlns="jabber:iq:auth"]""")

    def associateWithStream(self, xs):
        """do all the things necessary to register ourselves 
           with the xmlstream
        """
        self.xmlstream = xs
        if not self.xmlstream.initiating:
            self.xmlstream.addOnetimeObserver(xmlstream.STREAM_START_EVENT,
                                              self.streamStarted)

    def disassociateWithStream(self, xs):
        if not self.xmlstream.initiating:
            self.xmlstream.removeObserver(self.AUTH_FIELDS_REQUESTED_EVENT,
                                          self.authFieldsRequested)
            self.xmlstream.removeObserver(self.AUTH_FIELDS_PROVIDED_EVENT,
                                          self.authFieldsProvided)
        self.xmlstream = None
       
    #actions
    def authenticate(self):
        return self.provideAuthFields()

    def checkSupported(self, *args):
        """return a deferred, callback with self on success, errback"""
        return self.requestAuthFields()

    def requestAuthFields(self):
        iq = IQRequest("get")
        q = iq.addElement("query", "jabber:iq:auth")
        q.addElement("username", content=self.xmlstream.name)
        d = iq.send(self.xmlstream)
        d.addCallback(lambda _: self)
        return d

    def provideAuthFields(self):
        iq = IQRequest("set")
        iq.addElement("query", "jabber:iq:auth")
        iq.query.addElement("username", content=self.xmlstream.name)
        iq.query.addElement("digest", content="9f5e1dbdf5b65451bf6502eeda6eaa359319007c")
        if hasattr(self.xmlstream, "resource"):
            iq.query.addElement("resource", content=self.xmlstream.resource)
    
        d = iq.send(self.xmlstream)
        return d
        pass

    #callbacks
    def streamStarted(self, elm):
        if not self.xmlstream.initiating:
            self.xmlstream.addObserver(self.AUTH_FIELDS_REQUESTED_EVENT,
                                    self.authFieldsRequested)
            self.xmlstream.addObserver(self.AUTH_FIELDS_PROVIDED_EVENT,
                                    self.authFieldsProvided)
            

    def authFieldsRequested(self, elm):
        """return the types of auth fields that are supported"""

        print "auth fields requested!"
        resp = IQStanza(type="result", id=elm['id'])
        q = resp.addElement("query", "jabber:iq:auth")
        q.addElement("username", content=str(elm.query.username))
        q.addElement("digest")
        q.addElement("password")
        q.addElement("resource")

        self.xmlstream.send(resp)

    def authFieldsProvided(self, elm):
        """authenticate the user or return an error"""
        # XXX andy: theoretically this defers the actual authentication to
        #           the factory/service
        print "auth fields provided!"
        #user = JabberUser(self.xmlstream.host, str(elm.query.username), str(elm.query.resource))
        

        resp = IQStanza(type="result", id=elm['id'])
        self.xmlstream.send(resp)
        self.xmlstream.dispatch(None, STREAM_AUTHD_EVENT)