xmpp-20190522.py (Código fuente)

#!/usr/bin/env python3

# This code is in the Public Domain.
# You can do with it whatever you want.
#
# 2018-2019 jcea@jcea.es - https://www.jcea.es/ - https://blog.jcea.es/


import socket
import ssl
import base64
import sys
import xml.dom.minidom

import dns.resolver

jid = 'TU JID'
clave = 'TU CLAVE'

jids = sys.argv[1:]

usuario, dominio = jid.split('@')
dns = dns.resolver.query(f'_xmpp-client._tcp.{dominio}', 'SRV')
srv = min(dns.response.answer[0].items, key=lambda x: x.priority)

s = socket.socket()
s.connect((srv.target.to_text(), srv.port))

s.send(f"""<stream:stream
from='{jid}'
to='{dominio}'
version='1.0'
xml:lang='en'
xmlns='jabber:client'
xmlns:stream='http://etherx.jabber.org/streams'>
""".encode('utf-8'))
print(s.recv(9999))

s.send(b"<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>")
print(s.recv(9999))

ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS)
ssl_context.verify_mode = ssl.CERT_REQUIRED
ssl_context.check_hostname = True
ssl_context.load_default_certs()
s = ssl_context.wrap_socket(s, server_hostname=dominio)

print('\nPasamos a TLS\n')

s.send(f"""<stream:stream
from='{jid}'
to='{dominio}'
version='1.0'
xml:lang='en'
xmlns='jabber:client'
xmlns:stream='http://etherx.jabber.org/streams'>
""".encode('utf-8'))
print(s.recv(9999))

s.send(b"""
<auth mechanism='PLAIN'
xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>%s</auth>
""" % base64.b64encode(f'{jid}\0{usuario}\0{clave}'.encode('utf-8')))
print(s.recv(9999))

s.send(f"""<stream:stream
from='{jid}'
to='{dominio}'
version='1.0'
xml:lang='en'
xmlns='jabber:client'
xmlns:stream='http://etherx.jabber.org/streams'>
""".encode('utf-8'))
print(s.recv(9999))

s.send(b"""
<iq id='qwdc' type='set'>
<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>
<resource>DUMMY</resource>
</bind>
</iq>
""")
print(s.recv(9999))

print("\nPreguntamos por qué extensiones soporta el servidor\n")

s.send(f"""
<iq from='{jid}' to='{dominio}' type='get' id='abcd'>
  <query xmlns='http://jabber.org/protocol/disco#info'/>
</iq>
""".encode('utf-8'))
print(s.recv(9999))

if jids:
    print('\nPedimos bloqueos:')

    # https://xmpp.org/extensions/xep-0191.html
    stanza = f"""
<iq from='{jid}/DUMMY' type='set' id='block1'>
<block xmlns='urn:xmpp:blocking'>
"""
    for jid in jids:
        print(f'Pedimos el bloqueo de "{jid}"')
        stanza += f"<item jid ='{jid}'/>\n"
    stanza +="""
</block>
</iq>
"""
    print("\nBloqueando...\n")
    s.send(stanza.encode('utf-8'))
    print(s.recv(9999))

print("\nLista de JID bloqueados:")
s.send(b"""
<iq type='get' id='blocklist1'>
<blocklist xmlns='urn:xmpp:blocking'/>
</iq>
""")

xml = xml.dom.minidom.parseString(s.recv(9999)).toprettyxml()
# Nos saltamos el '<?xml version="1.0" ?>' inicial.
print(xml[xml.find('\n') + 1:])