cirandas.net

ref: master

public/javascripts/vendor/strophejs-1.1.3/examples/attach/boshclient.py


  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
import sys, os
import httplib, urllib
import random, binascii
from urlparse import urlparse

from punjab.httpb import HttpbParse

from twisted.words.xish import domish
from twisted.words.protocols.jabber import jid

TLS_XMLNS = 'urn:ietf:params:xml:ns:xmpp-tls'
SASL_XMLNS = 'urn:ietf:params:xml:ns:xmpp-sasl'
BIND_XMLNS = 'urn:ietf:params:xml:ns:xmpp-bind'
SESSION_XMLNS = 'urn:ietf:params:xml:ns:xmpp-session'


class BOSHClient:
    def __init__(self, jabberid, password, bosh_service):
        self.rid = random.randint(0, 10000000)
        self.jabberid = jid.internJID(jabberid)
        self.password = password

        self.authid = None
        self.sid = None
        self.logged_in = False
        self.headers = {"Content-type": "text/xml",
                        "Accept": "text/xml"}

	self.bosh_service = urlparse(bosh_service)
        
    def buildBody(self, child=None):
        """Build a BOSH body.
        """
        
        body = domish.Element(("http://jabber.org/protocol/httpbind", "body"))
        body['content'] = 'text/xml; charset=utf-8'
        self.rid = self.rid + 1
        body['rid'] = str(self.rid)
        body['sid'] = str(self.sid)
        body['xml:lang'] = 'en'
     
        if child is not None:
            body.addChild(child)

        return body
        
    def sendBody(self, body):
        """Send the body.
        """

        parser = HttpbParse(True)

        # start new session
        conn = httplib.HTTPConnection(self.bosh_service.netloc)
        conn.request("POST", self.bosh_service.path, 
		     body.toXml(), self.headers)

        response = conn.getresponse()
	data = ''
        if response.status == 200:
            data = response.read()
        conn.close()

        return parser.parse(data)

    def startSessionAndAuth(self, hold='1', wait='70'):
        # Create a session
        # create body
        body = domish.Element(("http://jabber.org/protocol/httpbind", "body"))

        body['content'] = 'text/xml; charset=utf-8'
        body['hold'] = hold
        body['rid'] = str(self.rid)
        body['to'] = self.jabberid.host
        body['wait'] = wait
        body['window'] = '5'
        body['xml:lang'] = 'en'


        retb, elems = self.sendBody(body)
        if type(retb) != str and retb.hasAttribute('authid') and \
		retb.hasAttribute('sid'):
            self.authid = retb['authid']
            self.sid = retb['sid']

            # go ahead and auth
            auth = domish.Element((SASL_XMLNS, 'auth'))
            auth['mechanism'] = 'PLAIN'
            
            # TODO: add authzid
            if auth['mechanism'] == 'PLAIN':
                auth_str = ""
                auth_str += "\000"
                auth_str += self.jabberid.user.encode('utf-8')
                auth_str += "\000"
                try:
                    auth_str += self.password.encode('utf-8').strip()
                except UnicodeDecodeError:
                    auth_str += self.password.decode('latin1') \
		        .encode('utf-8').strip()
                        
                auth.addContent(binascii.b2a_base64(auth_str))
                
                retb, elems = self.sendBody(self.buildBody(auth))
                if len(elems) == 0:
		    # poll for data
                    retb, elems = self.sendBody(self.buildBody())

                if len(elems) > 0:
                    if elems[0].name == 'success':
                        retb, elems = self.sendBody(self.buildBody())
                        
                        has_bind = False
                        for child in elems[0].children:
                            if child.name == 'bind':
                                has_bind = True
                                break

                        if has_bind:
                            iq = domish.Element(('jabber:client', 'iq'))
                            iq['type'] = 'set'
                            iq.addUniqueId()
                            iq.addElement('bind')
                            iq.bind['xmlns'] = BIND_XMLNS
                            if self.jabberid.resource:
				iq.bind.addElement('resource')
				iq.bind.resource.addContent(
				    self.jabberid.resource)

                            retb, elems = self.sendBody(self.buildBody(iq))
                            if type(retb) != str and retb.name == 'body':
                                # send session
                                iq = domish.Element(('jabber:client', 'iq'))
                                iq['type'] = 'set'
                                iq.addUniqueId()
                                iq.addElement('session')
                                iq.session['xmlns'] = SESSION_XMLNS

                                retb, elems = self.sendBody(self.buildBody(iq))

				# did not bind, TODO - add a retry?
                                if type(retb) != str and retb.name == 'body':
                                    self.logged_in = True
				    # bump up the rid, punjab already 
				    # received self.rid
                                    self.rid += 1


if __name__ == '__main__':
    USERNAME = sys.argv[1]
    PASSWORD = sys.argv[2]
    SERVICE = sys.argv[3]

    c = BOSHClient(USERNAME, PASSWORD, SERVICE)
    c.startSessionAndAuth()

    print c.logged_in