q = u"""
id='disco1'
to='juliet@capulet.lit/chamber'
type='result'>
urn:xmpp:dataforms:softwareinfo
Mac
ipv6
ipv4
10.5.1
Psi
0.11
"""
from sha import sha
import xml.etree.ElementTree as etree
import sys
iq = etree.fromstring(q.encode('utf8'))
# 0. Initialize an empty string S.
S = ''
# 1. Sort the service discovery identities [14] by category and then
# by type (if it exists) and then by xml:lang (if it exists),
# formatted as CATEGORY '/' [TYPE] '/' [LANG] '/' [NAME]. Note that
# each slash is included even if the TYPE, LANG, or NAME is not
# included.
query = iq.find("{http://jabber.org/protocol/disco#info}query")
ids = []
for i in query.findall('{http://jabber.org/protocol/disco#info}identity'):
ids.append([i.get("category"),
i.get("type") or "",
i.get("{http://www.w3.org/XML/1998/namespace}lang") or "",
i.get("name")] or "")
ids.sort()
# 2. For each identity, append the 'category/type/lang/name' to S,
# followed by the '<' character.
for i in ids:
S += "/".join(i) + "<"
# 3. Sort the supported service discovery features. [15]
feats = []
for f in query.findall('{http://jabber.org/protocol/disco#info}feature'):
feats.append(f.get("var"))
feats.sort()
# 4. For each feature, append the feature to S, followed by the '<'
# character.
for f in feats:
S += f + "<"
# 5. If the service discovery information response includes XEP-0128
# data forms, sort the forms by the FORM_TYPE field.
forms = {}
for x in query.findall("{jabber:x:data}x"):
typ = None
form = []
for field in x.findall("{jabber:x:data}field"):
values = []
for v in field.findall("{jabber:x:data}value"):
values.append(v.text)
name = field.get("var")
if name == "FORM_TYPE":
if typ:
print "two FORM_TYPEs"
sys.exit(1)
typ = values[0]
else:
form.append([name, values])
if typ:
if typ in forms:
print "two FORM_TYPEs the same"
sys.exit(1)
forms[typ] = form
forms = forms.items()
forms.sort()
# 6. For each extended service discovery information form:
for typ, fields in forms:
# 0. Append the value of the FORM_TYPE field, followed by the '<' character.
S += typ + "<"
# 1. Sort the fields by the value of the "var" attribute.
fields.sort()
# 2. For each field:
for var, vals in fields:
# 0. Append the value of the "var" attribute, followed by the
# '<' character.
S += var + "<"
# 1. Sort values by the XML character data of the
# element.
vals.sort()
# 2. For each element, append the XML character data,
# followed by the '<' character.
for v in vals:
S += v + "<"
print S
print
# 7. Compute ver by hashing S using the algorithm specified in the
# 'hash' attribute (e.g., SHA-1 as defined in RFC 3174 [16]). The
# hashed data MUST be generated with binary output and encoded using
# Base64 as specified in Section 4 of RFC 4648 [17] (note: the Base64
# output MUST NOT include whitespace and MUST set padding bits to
# zero). [18]
print sha(S.encode('utf8')).digest().encode('base64')