summaryrefslogtreecommitdiff
path: root/xmpp.lua
diff options
context:
space:
mode:
authorubq323 <ubq323@ubq323.website>2025-02-25 23:43:41 +0000
committerubq323 <ubq323@ubq323.website>2025-02-25 23:43:41 +0000
commit4dec20e4ff11b61be57a6cfbdb289327d9e1eb7d (patch)
treecc2ffe0357c1110236270ad46dc2006cdb01bf89 /xmpp.lua
parente03937bbe51f3dd8e0d8ecc732999f5c4578fa94 (diff)
the Restructuring
Diffstat (limited to 'xmpp.lua')
-rw-r--r--xmpp.lua187
1 files changed, 0 insertions, 187 deletions
diff --git a/xmpp.lua b/xmpp.lua
deleted file mode 100644
index 5c3371b..0000000
--- a/xmpp.lua
+++ /dev/null
@@ -1,187 +0,0 @@
-local cqueues = require'cqueues'
-local cqaux = require'cqueues.auxlib'
-local socket = require'cqueues.socket'
-local xml = require'xml'
-local X = xml.X
-local xmlify = xml.xmlify
-local pprint=require'pprint'
-local Queue = require'queue'
-local base64 = require'base64'
-local sha1 = require'sha1'
-local Channel = require'channel'
-
-local Xmpp = {}
-
-local function make_auth(authz, authn, password)
- -- sasl plain (RFC4616)
- return base64.encode(authz..'\0'..authn..'\0'..password)
-end
-
-function Xmpp.make(wilson, conf)
- local self = {
- name = conf.name,
- wilson = wilson,
- inbox = Queue.make(),
- cq = wilson.cq, -- todo
- nicks_inuse = {}, -- todo
- }
- local function conf_var(name)
- assert(conf[name] ~= nil, 'missing conf field '..name)
- self[name] = conf[name]
- end
- -- conf_var 'jid'
- conf_var 'server'
- -- conf_var 'resource'
- conf_var 'component'
- conf_var 'component_secret'
-
- setmetatable(self, {__index=Xmpp})
- return self
-end
-
-function Xmpp._connect_c2s(self)
- local sock = assert(socket.connect(self.server, 5222))
- self.sock = sock
- sock:setmode('bn','bn')
-
- local start = ([[
-<?xml version='1.0'?><stream:stream from='%s' to='%s' version='1.0' xml:lang='en' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams'>]]):format(self.jid, self.server)
-
- -- state of the art xml parser
- local function check_and_send(test, text)
- local x = sock:read('-2048')
- assert(x:find(test))
- if text then sock:write(text) end
- end
- local function ietf_urn(v) return 'urn:ietf:params:xml:ns:xmpp-'..v end
-
- sock:write(start)
- check_and_send('starttls', xmlify(X.starttls{xmlns=ietf_urn"tls"}))
- check_and_send('proceed', nil)
- sock:starttls()
- sock:write(start)
- local auth = make_auth('', self.jid:match"(.*)@", self.password)
- check_and_send('PLAIN',
- xmlify(X.auth{xmlns=ietf_urn"sasl", mechanism='PLAIN', auth}))
- check_and_send('success',start)
- check_and_send('bind',
- xmlify(X.iq{type='set', id='aaaa',
- X.bind{xmlns=ietf_urn"bind", X.resource{self.resource}}}))
- check_and_send('jid',X.presence{X.show{'chat'}})
-
- return sock
-end
-
--- this sucks! no tls! no security! only use on local connections!
-function Xmpp._connect_component(self)
- local sock = assert(socket.connect(self.server, 5347))
- self.sock = sock
- sock:setmode('bn','bn')
- -- yes, our component name goes in the 'to' field. don't ask me why
- local start = ([[<stream:stream to='%s' xmlns='jabber:component:accept' xmlns:stream='http://etherx.jabber.org/streams'>]]):format(self.component)
-
- print(start)
-
- -- state of the art xml parser
- local function check_and_send(test, text)
- local x = sock:read('-2048')
- assert(x:find(test))
- if text then sock:write(text) end
- end
-
- sock:write(start)
- local streamhead = sock:read('-2048')
- print('streamhead', streamhead)
- assert(streamhead:find'accept')
- local streamid = streamhead:match"id='(.-)'"
- sock:write(xmlify(X.handshake{sha1.sha1(streamid..self.component_secret)}))
- check_and_send('<handshake/>',nil)
-
- return sock
-end
-
-local THE_MUC = 'd@conference.ubq323.website'
-
-function Xmpp.run(self)
- self:_connect_component()
- self.cq:wrap(self.recving, self)
- self.cq:wrap(self.sending, self)
-end
-
-function Xmpp.recving(self)
- local function getmore()
- local function t(...)
- pprint(...)
- return ...
- end
- return t(self.sock:read'-2048')
- end
- for x in xml.stanzae(getmore) do
- pprint(x)
- print(xmlify(x))
- local body = x'body' and x'body'[1]
- if x.label == 'message' then
- local fr = x.xarg.from
- local t = x.xarg.to
- local from_nick = fr:match("/(.*)")
- if not self.nicks_inuse[from_nick] and body and fr:match"/" and t == 'wilson@'..self.component then
- self.wilson:deliver(Channel(self, THE_MUC), {
- body = body,
- sender = '[x]'..from_nick
- })
- end
- end
- end
-end
-
-function Xmpp.sending(self)
- local users_inuse = {}
- local function ensure_joined(muc,user,nick)
- if self.nicks_inuse[nick] then return end
- user = user:gsub("[^a-zA-Z0-9%.]","."):match("^%.*(.-)%.*$")
- while users_inuse[user] do user = user..'-' end
- local jid = user..'@'..self.component
- local mucjid = muc..'/'..nick
- self.nicks_inuse[nick] = true
- users_inuse[user] = true
-
- self.sock:write(xmlify(
- X.presence{from=jid, to=mucjid,
- X.x{xmlns='http://jabber.org/protocol/muc',
- X.history{maxstanzas='0'}}}))
- end
- ensure_joined(THE_MUC, 'wilson', 'wilson')
- for dest_channel, message in self.inbox:iter() do
- pprint(dest_channel, message)
- ensure_joined(THE_MUC, message.sender, message.sender)
- local user = message.sender:gsub("[^a-zA-Z0-9%.]","."):match("^%.*(.-)%.*$")
- local jid = user..'@'..self.component
- self.sock:write(xmlify(
- X.message{to=THE_MUC, type='groupchat', from=jid,
- X.body{message.body}}))
- end
-end
-
-function Xmpp.post(self, dest_channel, message)
- self.inbox:enqueue(dest_channel, message)
-end
-
-return Xmpp
-
--- local cq = cqueues.new()
--- local conf = {
--- jid='wilson@ubq323.website',
--- server='ubq323.website',
--- password='gregory<3',
--- resource='cheese',
--- }
--- local dummy_network = {
--- post = function(self, pylonname, channel, message)
--- pprint(pylonname, channel, message)
--- end
--- }
--- local pylon = Xmpp.makepylon('xmpptest',conf, cq, dummy_network)
--- pylon:run()
-
--- pprint('peas', cq:loop())
-