diff options
| author | ubq323 <ubq323@ubq323.website> | 2025-02-25 23:43:41 +0000 |
|---|---|---|
| committer | ubq323 <ubq323@ubq323.website> | 2025-02-25 23:43:41 +0000 |
| commit | 4dec20e4ff11b61be57a6cfbdb289327d9e1eb7d (patch) | |
| tree | cc2ffe0357c1110236270ad46dc2006cdb01bf89 /xmpp.lua | |
| parent | e03937bbe51f3dd8e0d8ecc732999f5c4578fa94 (diff) | |
the Restructuring
Diffstat (limited to 'xmpp.lua')
| -rw-r--r-- | xmpp.lua | 187 |
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()) - |
