def vipadia_command(self, iq): dbg("vipadia_command:\n%s" % (fmt_evt(iq), )) items = iq.xpath_eval("v:command/v:item", { "v": "http://vipadia.com/skype", }) for item in items: command = item.prop("command") if command == "message": ujid = JID(item.prop("ujid")) message = item.prop("message") dbg(" +ujid:%s precedingmessage:%s" % ( ujid.as_utf8(), PrecedingMessage, )) if ujid in PrecedingMessage and PrecedingMessage[ ujid] == message: continue PrecedingMessage[ujid] = message self.safe_send(Message(to_jid=ujid, body=message)) dbg(" -ujid:%s precedingmessage:%s" % ( ujid.as_utf8(), PrecedingMessage, )) return True
def vipadia_iq(self, iq): dbg("vipadia_iq:\n%s" % (fmt_evt(iq),), 3) items = iq.xpath_eval("v:query/v:item", { "v": "http://vipadia.com/skype", }) for item in items: jid = JID(item.prop("dialback")) (_, screen, _) = jid.resource.split(":") secret = item.prop("secret") skypeuser = item.prop("skypeuser") skypesecret = item.prop("skypesecret") xmppujid = item.prop("xmppujid") mode = item.prop("mode") marketing_message = item.prop("marketing-message") argstring = base64.b64encode( "%s\0%s\0%s\0%s\0%s\0%s\0%s\0%s\0%s\0%s" % ( jid.as_utf8(), secret, skypeuser, skypesecret, xmppujid, mode, self.config.master, self.config.muc, "%s@%s" % (self.config.slave, self.config.domain), marketing_message, )) cmd = [ "./karaka/bundle.sh", screen, argstring ] dbg(" cmd:%s" % (cmd,)) ps = subprocess.Popen(cmd, stdout=subprocess.PIPE) return True
def vipadia_iq(self, iq): dbg("vipadia_iq:\n%s" % (fmt_evt(iq), ), 3) items = iq.xpath_eval("v:query/v:item", { "v": "http://vipadia.com/skype", }) for item in items: jid = JID(item.prop("dialback")) (_, screen, _) = jid.resource.split(":") secret = item.prop("secret") skypeuser = item.prop("skypeuser") skypesecret = item.prop("skypesecret") xmppujid = item.prop("xmppujid") mode = item.prop("mode") marketing_message = item.prop("marketing-message") argstring = base64.b64encode( "%s\0%s\0%s\0%s\0%s\0%s\0%s\0%s\0%s\0%s" % ( jid.as_utf8(), secret, skypeuser, skypesecret, xmppujid, mode, self.config.master, self.config.muc, "%s@%s" % (self.config.slave, self.config.domain), marketing_message, )) cmd = ["./karaka/bundle.sh", screen, argstring] dbg(" cmd:%s" % (cmd, )) ps = subprocess.Popen(cmd, stdout=subprocess.PIPE) return True
def vipadia_command(self, iq): dbg("vipadia_command:\n%s" % (fmt_evt(iq),)) items = iq.xpath_eval("v:command/v:item", { "v": "http://vipadia.com/skype", }) for item in items: command = item.prop("command") if command == "message": ujid = JID(item.prop("ujid")) message = item.prop("message") dbg(" +ujid:%s precedingmessage:%s" % (ujid.as_utf8(), PrecedingMessage,)) if ujid in PrecedingMessage and PrecedingMessage[ujid] == message: continue PrecedingMessage[ujid] = message self.safe_send(Message(to_jid=ujid, body=message)) dbg(" -ujid:%s precedingmessage:%s" % (ujid.as_utf8(), PrecedingMessage,)) return True
def _spawn(self, frm, user, secret): dbg("_spawn: frm:%s user:%s secret:%s" % (frm.as_utf8(), user, secret)) ujid = frm.bare() ## don't spawn if one already exists for this user if ujid in St['users']: return self.regdb.log_start(ujid.as_utf8(), user) # log it (slavejid, screen) = self.allocate_djid() if not slavejid: return "resource-constraint" djid = JID("%s@%s/%s:%s:%s" % (self.config.dialback, self.config.domain, slavejid.node, screen, hash(ujid))) dbg(" before avail: St['slots']:%s St['dialback_slave']:%s" % (St['slots'], St['dialback_slave'])) St['slots'][slavejid][screen] = djid St['dialback_slave'][djid] = (slavejid, screen) dbg(" after avail: St['slots']:%s St['dialback_slave']:%s" % (St['slots'], St['dialback_slave'])) St['dialbacks'][djid] = ujid St['users'][ujid] = djid if ujid not in St['userjids']: St['userjids'][ujid] = {} St['userjids'][ujid][frm] = None St['dialback_online'][djid] = DIALBACK.pending spawn = Iq(to_jid=slavejid, from_jid=self.config.component, stanza_type="set") query = spawn.new_query('http://vipadia.com/skype', "query") add_child(query, "item", attrs={ "skypeuser": user, "skypesecret": secret, "dialback": djid.as_utf8(), "secret": self.config.dialback_secret, "xmppujid": ujid.as_utf8(), "mode": CLIENT_MODE, "marketing-message": self.regdb.get_marketing_message(frm.as_utf8()), }) dbg(" spawn:\n%s" % (fmt_evt(spawn), )) self.safe_send(spawn)
def slave_online(self): slavejid = JID("%s@%s/slave" % (self.config.slave, self.config.domain)) iq = Iq(to_jid=self.config.master, from_jid=slavejid, stanza_type="set") command = iq.new_query('http://vipadia.com/skype', "command") digest = generate_slave_digest(str(slavejid.as_utf8()), self.config.slave_secret) add_child(command, "item", attrs={ "command": "slave-online", "capacity": self.config.capacity, "base": self.config.base, "digest": digest }) dbg(" iq:\n%s" % (fmt_evt(iq),)) self.safe_send(iq)
def slave_online(self): slavejid = JID("%s@%s/slave" % (self.config.slave, self.config.domain)) iq = Iq(to_jid=self.config.master, from_jid=slavejid, stanza_type="set") command = iq.new_query('http://vipadia.com/skype', "command") digest = generate_slave_digest(str(slavejid.as_utf8()), self.config.slave_secret) add_child(command, "item", attrs={ "command": "slave-online", "capacity": self.config.capacity, "base": self.config.base, "digest": digest }) dbg(" iq:\n%s" % (fmt_evt(iq), )) self.safe_send(iq)
def _spawn(self, frm, user, secret): dbg("_spawn: frm:%s user:%s secret:%s" % (frm.as_utf8(), user, secret)) ujid = frm.bare() ## don't spawn if one already exists for this user if ujid in St['users']: return self.regdb.log_start(ujid.as_utf8(), user) # log it (slavejid, screen) = self.allocate_djid() if not slavejid: return "resource-constraint" djid = JID("%s@%s/%s:%s:%s" % ( self.config.dialback, self.config.domain, slavejid.node, screen, hash(ujid))) dbg(" before avail: St['slots']:%s St['dialback_slave']:%s" % ( St['slots'], St['dialback_slave'])) St['slots'][slavejid][screen] = djid St['dialback_slave'][djid] = (slavejid, screen) dbg(" after avail: St['slots']:%s St['dialback_slave']:%s" % ( St['slots'], St['dialback_slave'])) St['dialbacks'][djid] = ujid St['users'][ujid] = djid if ujid not in St['userjids']: St['userjids'][ujid] = {} St['userjids'][ujid][frm] = None St['dialback_online'][djid] = DIALBACK.pending spawn = Iq(to_jid=slavejid, from_jid=self.config.component, stanza_type="set") query = spawn.new_query('http://vipadia.com/skype', "query") add_child(query, "item", attrs={ "skypeuser": user, "skypesecret": secret, "dialback": djid.as_utf8(), "secret": self.config.dialback_secret, "xmppujid": ujid.as_utf8(), "mode": CLIENT_MODE, "marketing-message": self.regdb.get_marketing_message(frm.as_utf8()), }) dbg(" spawn:\n%s" % (fmt_evt(spawn),)) self.safe_send(spawn)
class _Register(JabberClient): def __init__(self, config): self.config = config self.connection = CONNECTION.idle self.running = True self.jid = JID("%s@%s/%s" % (config.register, config.domain, config.register)) log("register: jid:%s" % (self.jid.as_utf8(),)) tls = streamtls.TLSSettings(require=True, verify_peer=False) auth = [ 'digest' ] JabberClient.__init__(self, self.jid, self.config.secret, disco_name="Vipadia Skype Gateway Register", disco_type="bot", tls_settings=tls, auth_methods=auth) def stream_state_changed(self, state, arg): dbg("stream_state_changed: %s %r" % (state, arg), 3) def safe_send(self, stanza): to = stanza.get_to() if not to.domain.endswith(self.config.domain): to = to.bare() stanza = Stanza(stanza, to_jid=to) dbg("tx:\n%s" % (fmt_evt(stanza),)) self.stream.send(stanza) def session_started(self): log("session_started: jid:%s" % (self.jid.as_utf8(),)) self.connection = CONNECTION.connected JabberClient.session_started(self) self.stream.set_message_handler("normal", self.message) self.stream.set_presence_handler("subscribe", self.subscription) self.stream.set_iq_set_handler( "command", "http://vipadia.com/skype", self.vipadia_command) global Connected Connected = True self.safe_send(Presence(to_jid=self.config.master, stanza_type="subscribe")) # # message handler # def message(self, stanza): dbg("message:\nfrm:%s to:%s" % ( stanza.get_from().as_utf8(), stanza.get_to().as_utf8(),), 3) global RegDB body = stanza.get_body() frm = stanza.get_from() user = stanza.get_from().bare().as_utf8() ujid = JID(user) dbg(" ++ujid:%s precedingmessage:%s" % (ujid.as_utf8(), PrecedingMessage,)) if ujid in PrecedingMessage: del PrecedingMessage[ujid] dbg(" --ujid:%s precedingmessage:%s" % (ujid.as_utf8(), PrecedingMessage,)) if body: cmd = body.split() if len(cmd) > 0 : reply = "" if cmd[0].lower() == "register": if len(cmd) != 3: reply = "error, please use: register <skypeuser> <skypepassword>" skypeuser = cmd[1] skypepass = cmd[2] RegDB.remove_credentials(user) RegDB.set_credentials_plain(user, skypeuser, skypepass) reply = "Registration successful for " + skypeuser message = Message(to_jid=stanza.get_from(), body=reply) self.safe_send(message) sub = Iq(to_jid=self.config.master, stanza_type="set") query = sub.new_query('http://vipadia.com/skype', "command") add_child(query, "item", attrs={ "command" : "register-available", "jid": frm.as_utf8() }) dbg(" sub:\n%s" % (fmt_evt(sub),)) self.safe_send(sub) reply = "Presence request sent" elif cmd[0].lower() == "register-carrier": if len(cmd) != 3: reply = "error, please use: register <skypeuser> <skypepassword>" skypeuser = cmd[1] ## KeyCzar ## crypter = keyczar.Encrypter.Read(PUBLIC_KEYLOC) skypesecret = cmd[2] ## KeyCzar ## skypesecret = crypter.Encrypt(str(skypesecret)) spawn = Iq(to_jid=self.config.master, stanza_type="set") command = spawn.new_query("http://vipadia.com/skype", "command") add_child(command, "item", attrs={ "command": "spawn", "ujid": frm.as_utf8(), "skypeuser": skypeuser, "skypesecret": skypesecret, }) self.safe_send(spawn) elif cmd[0].lower() == "unregister": if len(cmd) == 1: RegDB.remove_credentials(user) reply = "Unregistration successful" else: reply = "Skype Registration Commands:\r\n" + \ " register <skypeuser> <skypepass>\r\n" + \ " unregister" message = Message(to_jid=stanza.get_from(), body=reply) self.safe_send(message) return True # # presence handlers # def subscription(self, stanza): dbg("subscription:\n%s" % (fmt_evt(stanza),), 3) send_response = not (stanza.get_type() == 'subscribed') if send_response: self.safe_send(stanza.make_accept_response()) return True # # iq handlers # def vipadia_command(self, iq): dbg("vipadia_command:\n%s" % (fmt_evt(iq),)) items = iq.xpath_eval("v:command/v:item", { "v": "http://vipadia.com/skype", }) for item in items: command = item.prop("command") if command == "message": ujid = JID(item.prop("ujid")) message = item.prop("message") dbg(" +ujid:%s precedingmessage:%s" % (ujid.as_utf8(), PrecedingMessage,)) if ujid in PrecedingMessage and PrecedingMessage[ujid] == message: continue PrecedingMessage[ujid] = message self.safe_send(Message(to_jid=ujid, body=message)) dbg(" -ujid:%s precedingmessage:%s" % (ujid.as_utf8(), PrecedingMessage,)) return True
def message(self, stanza): dbg("message:\nfrm:%s to:%s" % ( stanza.get_from().as_utf8(), stanza.get_to().as_utf8(),), 3) global RegDB body = stanza.get_body() frm = stanza.get_from() user = stanza.get_from().bare().as_utf8() ujid = JID(user) dbg(" ++ujid:%s precedingmessage:%s" % (ujid.as_utf8(), PrecedingMessage,)) if ujid in PrecedingMessage: del PrecedingMessage[ujid] dbg(" --ujid:%s precedingmessage:%s" % (ujid.as_utf8(), PrecedingMessage,)) if body: cmd = body.split() if len(cmd) > 0 : reply = "" if cmd[0].lower() == "register": if len(cmd) != 3: reply = "error, please use: register <skypeuser> <skypepassword>" skypeuser = cmd[1] skypepass = cmd[2] RegDB.remove_credentials(user) RegDB.set_credentials_plain(user, skypeuser, skypepass) reply = "Registration successful for " + skypeuser message = Message(to_jid=stanza.get_from(), body=reply) self.safe_send(message) sub = Iq(to_jid=self.config.master, stanza_type="set") query = sub.new_query('http://vipadia.com/skype', "command") add_child(query, "item", attrs={ "command" : "register-available", "jid": frm.as_utf8() }) dbg(" sub:\n%s" % (fmt_evt(sub),)) self.safe_send(sub) reply = "Presence request sent" elif cmd[0].lower() == "register-carrier": if len(cmd) != 3: reply = "error, please use: register <skypeuser> <skypepassword>" skypeuser = cmd[1] ## KeyCzar ## crypter = keyczar.Encrypter.Read(PUBLIC_KEYLOC) skypesecret = cmd[2] ## KeyCzar ## skypesecret = crypter.Encrypt(str(skypesecret)) spawn = Iq(to_jid=self.config.master, stanza_type="set") command = spawn.new_query("http://vipadia.com/skype", "command") add_child(command, "item", attrs={ "command": "spawn", "ujid": frm.as_utf8(), "skypeuser": skypeuser, "skypesecret": skypesecret, }) self.safe_send(spawn) elif cmd[0].lower() == "unregister": if len(cmd) == 1: RegDB.remove_credentials(user) reply = "Unregistration successful" else: reply = "Skype Registration Commands:\r\n" + \ " register <skypeuser> <skypepass>\r\n" + \ " unregister" message = Message(to_jid=stanza.get_from(), body=reply) self.safe_send(message) return True
args = base64.b64decode(sys.argv[1]).split("\0") dbg(" args:[%d] %s" % (len(args), args,)) jid, secret, skypeuser, skypesecret, xmppujid, \ Mode, Master, Muc, Slave, Marketing_message = args jid = JID(jid) xmppujid = JID(xmppujid) logger = logging.getLogger() logger.addHandler(logging.FileHandler("/tmp/bundle-%s.log" % jid.resource)) logger.setLevel(logging.DEBUG) # change to DEBUG for higher verbosity try: log("bundle: jid:%s xmppujid:%s" % (jid.as_utf8(), xmppujid.as_utf8())) Bundle = SkypeBundle(jid, secret, skypeuser, skypesecret, xmppujid) attempts = 0 keepalive = Iq(to_jid=Slave, stanza_type="set") keptalive = 0 while Bundle.running: try: if Bundle.connection == CONNECTION.idle: dbg("bundle [%s] connecting" % (jid.as_utf8(),)) Bundle.connect() Bundle.connection = CONNECTION.connecting elif Bundle.connection == CONNECTION.connecting: dbg("bundle [%s] connecting..." % (jid.as_utf8(),)) if Bundle.stream: Bundle.stream.loop_iter(1)
def vipadia_command(self, iq): dbg("vipadia_command:\n%s" % (fmt_evt(iq),)) StLock.acquire() try: items = iq.xpath_eval("v:command/v:item", { "v": "http://vipadia.com/skype", }) for item in items: command = item.prop("command") if command == "subscribe": djid = JID(item.prop("djid")) if djid not in St['dialbacks']: self.safe_send(iq.make_result_response()) return True self.safe_send(Presence( to_jid=St['dialbacks'][djid], from_jid=item.prop("from"), stanza_type="subscribe")) elif command == "subscribed": frm = JID("%s@%s" % (item.prop("from"), self.config.component)) ujid = St['dialbacks'][get_from(iq)] self.safe_send(Presence( to_jid=ujid, from_jid=frm, stanza_type="subscribed")) elif command == "register-subscribe": jid = JID(item.prop("jid")) self.safe_send(Presence( to_jid=jid.bare(), from_jid=self.config.component, stanza_type="subscribe")) elif command == "register-available": jid = JID(item.prop("jid")) fake_available = Presence(to_jid=self.config.component, from_jid=jid) self.presence_available(fake_available) elif command == "out-subscribe": frm = JID("%s@%s" % (item.prop("from"), self.config.component)) iq_frm = get_from(iq) if iq_frm not in St['dialbacks']: self.safe_send(iq.make_result_response()) return True ujid = St['dialbacks'][iq_frm] self.safe_send(Presence( to_jid=ujid, from_jid=frm, stanza_type="subscribe")) elif command == "slave-online": frm = get_from(iq) digest = str(item.prop("digest")) if not self.is_valid_slave(frm.as_utf8(), digest): err("invalid slave! frm:%s iq:\n%s" % (frm.as_utf8(), fmt_evt(iq))) self.safe_send(iq.make_error_response("forbidden")) return True capacity = int(item.prop("capacity")) base = int(item.prop("base")) St['slaves'][frm] = None St['slots'][frm] = {} dbg(" before St['slots']:%s" % (St['slots'],)) for i in range(base, base+capacity): if i not in St['slots'][frm]: St['slots'][frm][i] = None dbg(" after St['slots']:%s" % (St['slots'],)) self.safe_send(Presence( to_jid=frm, from_jid=self.config.component, stanza_type="subscribe")) elif command == "spawn": ujid = item.prop("ujid") skypeuser = item.prop("skypeuser") skypesecret = item.prop("skypesecret") errstr = self._spawn(JID(ujid), skypeuser, skypesecret) if errstr: err("_spawn error! errstr:%s" % (errstr,)) else: err("unknown command! command:%s\n%s" % (command, fmt_evt(iq),)) self.safe_send(iq.make_error_response("feature-not-implemented")) return True self.safe_send(iq.make_result_response()) return True finally: StLock.release()
def message(self, stanza): dbg( "message:\nfrm:%s to:%s" % ( stanza.get_from().as_utf8(), stanza.get_to().as_utf8(), ), 3) global RegDB body = stanza.get_body() frm = stanza.get_from() user = stanza.get_from().bare().as_utf8() ujid = JID(user) dbg(" ++ujid:%s precedingmessage:%s" % ( ujid.as_utf8(), PrecedingMessage, )) if ujid in PrecedingMessage: del PrecedingMessage[ujid] dbg(" --ujid:%s precedingmessage:%s" % ( ujid.as_utf8(), PrecedingMessage, )) if body: cmd = body.split() if len(cmd) > 0: reply = "" if cmd[0].lower() == "register": if len(cmd) != 3: reply = "error, please use: register <skypeuser> <skypepassword>" skypeuser = cmd[1] skypepass = cmd[2] RegDB.remove_credentials(user) RegDB.set_credentials_plain(user, skypeuser, skypepass) reply = "Registration successful for " + skypeuser message = Message(to_jid=stanza.get_from(), body=reply) self.safe_send(message) sub = Iq(to_jid=self.config.master, stanza_type="set") query = sub.new_query('http://vipadia.com/skype', "command") add_child(query, "item", attrs={ "command": "register-available", "jid": frm.as_utf8() }) dbg(" sub:\n%s" % (fmt_evt(sub), )) self.safe_send(sub) reply = "Presence request sent" elif cmd[0].lower() == "register-carrier": if len(cmd) != 3: reply = "error, please use: register <skypeuser> <skypepassword>" skypeuser = cmd[1] ## KeyCzar ## crypter = keyczar.Encrypter.Read(PUBLIC_KEYLOC) skypesecret = cmd[2] ## KeyCzar ## skypesecret = crypter.Encrypt(str(skypesecret)) spawn = Iq(to_jid=self.config.master, stanza_type="set") command = spawn.new_query("http://vipadia.com/skype", "command") add_child(command, "item", attrs={ "command": "spawn", "ujid": frm.as_utf8(), "skypeuser": skypeuser, "skypesecret": skypesecret, }) self.safe_send(spawn) elif cmd[0].lower() == "unregister": if len(cmd) == 1: RegDB.remove_credentials(user) reply = "Unregistration successful" else: reply = "Skype Registration Commands:\r\n" + \ " register <skypeuser> <skypepass>\r\n" + \ " unregister" message = Message(to_jid=stanza.get_from(), body=reply) self.safe_send(message) return True
class SkypeSlave(JabberClient): def __init__(self, config): self.config = config self.running = True self.connection = CONNECTION.idle self.jid = JID("%s@%s/slave" % (config.slave, config.domain,)) log("slave: jid:%s" % (self.jid.as_utf8(),)) tls = streamtls.TLSSettings(require=True, verify_peer=False) auth = [ 'digest' ] JabberClient.__init__(self, self.jid, self.config.secret, disco_name="Vipadia Skype Gateway Slave", disco_type="bot", tls_settings=tls, auth_methods=auth) def safe_send(self, stanza): to = stanza.get_to() if not to.domain.endswith(self.config.domain): to = to.bare() stanza = Stanza(stanza, to_jid=to) dbg("tx:\n%s" % (fmt_evt(stanza),)) self.stream.send(stanza) def stream_state_changed(self, state, arg): dbg("stream_state_changed: %s %r" % (state, arg), 3) def session_started(self): log("session_started: jid:%s" % (self.jid.as_utf8(),)) self.connection = CONNECTION.connected JabberClient.session_started(self) self.stream.set_presence_handler("subscribe", self.subscribe) self.stream.set_iq_set_handler( "query", "http://vipadia.com/skype", self.vipadia_iq) self.slave_online() def slave_online(self): slavejid = JID("%s@%s/slave" % (self.config.slave, self.config.domain)) iq = Iq(to_jid=self.config.master, from_jid=slavejid, stanza_type="set") command = iq.new_query('http://vipadia.com/skype', "command") digest = generate_slave_digest(str(slavejid.as_utf8()), self.config.slave_secret) add_child(command, "item", attrs={ "command": "slave-online", "capacity": self.config.capacity, "base": self.config.base, "digest": digest }) dbg(" iq:\n%s" % (fmt_evt(iq),)) self.safe_send(iq) def disconnected(self): log("slave disconnected! jid:%s" % (self.jid.as_utf8(),)) self.connection = CONNECTION.error def subscribe(self, presence): dbg("subscribe: presence:\n%s" % (fmt_evt(presence),)) resp = presence.make_accept_response() dbg(" resp:\n%s" % (fmt_evt(resp),)) self.safe_send(resp) def vipadia_iq(self, iq): dbg("vipadia_iq:\n%s" % (fmt_evt(iq),), 3) items = iq.xpath_eval("v:query/v:item", { "v": "http://vipadia.com/skype", }) for item in items: jid = JID(item.prop("dialback")) (_, screen, _) = jid.resource.split(":") secret = item.prop("secret") skypeuser = item.prop("skypeuser") skypesecret = item.prop("skypesecret") xmppujid = item.prop("xmppujid") mode = item.prop("mode") marketing_message = item.prop("marketing-message") argstring = base64.b64encode( "%s\0%s\0%s\0%s\0%s\0%s\0%s\0%s\0%s\0%s" % ( jid.as_utf8(), secret, skypeuser, skypesecret, xmppujid, mode, self.config.master, self.config.muc, "%s@%s" % (self.config.slave, self.config.domain), marketing_message, )) cmd = [ "./karaka/bundle.sh", screen, argstring ] dbg(" cmd:%s" % (cmd,)) ps = subprocess.Popen(cmd, stdout=subprocess.PIPE) return True
len(args), args, )) jid, secret, skypeuser, skypesecret, xmppujid, \ Mode, Master, Muc, Slave, Marketing_message = args jid = JID(jid) xmppujid = JID(xmppujid) logger = logging.getLogger() logger.addHandler(logging.FileHandler("/tmp/bundle-%s.log" % jid.resource)) logger.setLevel(logging.DEBUG) # change to DEBUG for higher verbosity try: log("bundle: jid:%s xmppujid:%s" % (jid.as_utf8(), xmppujid.as_utf8())) Bundle = SkypeBundle(jid, secret, skypeuser, skypesecret, xmppujid) attempts = 0 keepalive = Iq(to_jid=Slave, stanza_type="set") keptalive = 0 while Bundle.running: try: if Bundle.connection == CONNECTION.idle: dbg("bundle [%s] connecting" % (jid.as_utf8(), )) Bundle.connect() Bundle.connection = CONNECTION.connecting elif Bundle.connection == CONNECTION.connecting: dbg("bundle [%s] connecting..." % (jid.as_utf8(), )) if Bundle.stream: Bundle.stream.loop_iter(1)
class SkypeSlave(JabberClient): def __init__(self, config): self.config = config self.running = True self.connection = CONNECTION.idle self.jid = JID("%s@%s/slave" % ( config.slave, config.domain, )) log("slave: jid:%s" % (self.jid.as_utf8(), )) tls = streamtls.TLSSettings(require=True, verify_peer=False) auth = ['digest'] JabberClient.__init__(self, self.jid, self.config.secret, disco_name="Vipadia Skype Gateway Slave", disco_type="bot", tls_settings=tls, auth_methods=auth) def safe_send(self, stanza): to = stanza.get_to() if not to.domain.endswith(self.config.domain): to = to.bare() stanza = Stanza(stanza, to_jid=to) dbg("tx:\n%s" % (fmt_evt(stanza), )) self.stream.send(stanza) def stream_state_changed(self, state, arg): dbg("stream_state_changed: %s %r" % (state, arg), 3) def session_started(self): log("session_started: jid:%s" % (self.jid.as_utf8(), )) self.connection = CONNECTION.connected JabberClient.session_started(self) self.stream.set_presence_handler("subscribe", self.subscribe) self.stream.set_iq_set_handler("query", "http://vipadia.com/skype", self.vipadia_iq) self.slave_online() def slave_online(self): slavejid = JID("%s@%s/slave" % (self.config.slave, self.config.domain)) iq = Iq(to_jid=self.config.master, from_jid=slavejid, stanza_type="set") command = iq.new_query('http://vipadia.com/skype', "command") digest = generate_slave_digest(str(slavejid.as_utf8()), self.config.slave_secret) add_child(command, "item", attrs={ "command": "slave-online", "capacity": self.config.capacity, "base": self.config.base, "digest": digest }) dbg(" iq:\n%s" % (fmt_evt(iq), )) self.safe_send(iq) def disconnected(self): log("slave disconnected! jid:%s" % (self.jid.as_utf8(), )) self.connection = CONNECTION.error def subscribe(self, presence): dbg("subscribe: presence:\n%s" % (fmt_evt(presence), )) resp = presence.make_accept_response() dbg(" resp:\n%s" % (fmt_evt(resp), )) self.safe_send(resp) def vipadia_iq(self, iq): dbg("vipadia_iq:\n%s" % (fmt_evt(iq), ), 3) items = iq.xpath_eval("v:query/v:item", { "v": "http://vipadia.com/skype", }) for item in items: jid = JID(item.prop("dialback")) (_, screen, _) = jid.resource.split(":") secret = item.prop("secret") skypeuser = item.prop("skypeuser") skypesecret = item.prop("skypesecret") xmppujid = item.prop("xmppujid") mode = item.prop("mode") marketing_message = item.prop("marketing-message") argstring = base64.b64encode( "%s\0%s\0%s\0%s\0%s\0%s\0%s\0%s\0%s\0%s" % ( jid.as_utf8(), secret, skypeuser, skypesecret, xmppujid, mode, self.config.master, self.config.muc, "%s@%s" % (self.config.slave, self.config.domain), marketing_message, )) cmd = ["./karaka/bundle.sh", screen, argstring] dbg(" cmd:%s" % (cmd, )) ps = subprocess.Popen(cmd, stdout=subprocess.PIPE) return True
class _Register(JabberClient): def __init__(self, config): self.config = config self.connection = CONNECTION.idle self.running = True self.jid = JID("%s@%s/%s" % (config.register, config.domain, config.register)) log("register: jid:%s" % (self.jid.as_utf8(), )) tls = streamtls.TLSSettings(require=True, verify_peer=False) auth = ['digest'] JabberClient.__init__(self, self.jid, self.config.secret, disco_name="Vipadia Skype Gateway Register", disco_type="bot", tls_settings=tls, auth_methods=auth) def stream_state_changed(self, state, arg): dbg("stream_state_changed: %s %r" % (state, arg), 3) def safe_send(self, stanza): to = stanza.get_to() if not to.domain.endswith(self.config.domain): to = to.bare() stanza = Stanza(stanza, to_jid=to) dbg("tx:\n%s" % (fmt_evt(stanza), )) self.stream.send(stanza) def session_started(self): log("session_started: jid:%s" % (self.jid.as_utf8(), )) self.connection = CONNECTION.connected JabberClient.session_started(self) self.stream.set_message_handler("normal", self.message) self.stream.set_presence_handler("subscribe", self.subscription) self.stream.set_iq_set_handler("command", "http://vipadia.com/skype", self.vipadia_command) global Connected Connected = True self.safe_send( Presence(to_jid=self.config.master, stanza_type="subscribe")) # # message handler # def message(self, stanza): dbg( "message:\nfrm:%s to:%s" % ( stanza.get_from().as_utf8(), stanza.get_to().as_utf8(), ), 3) global RegDB body = stanza.get_body() frm = stanza.get_from() user = stanza.get_from().bare().as_utf8() ujid = JID(user) dbg(" ++ujid:%s precedingmessage:%s" % ( ujid.as_utf8(), PrecedingMessage, )) if ujid in PrecedingMessage: del PrecedingMessage[ujid] dbg(" --ujid:%s precedingmessage:%s" % ( ujid.as_utf8(), PrecedingMessage, )) if body: cmd = body.split() if len(cmd) > 0: reply = "" if cmd[0].lower() == "register": if len(cmd) != 3: reply = "error, please use: register <skypeuser> <skypepassword>" skypeuser = cmd[1] skypepass = cmd[2] RegDB.remove_credentials(user) RegDB.set_credentials_plain(user, skypeuser, skypepass) reply = "Registration successful for " + skypeuser message = Message(to_jid=stanza.get_from(), body=reply) self.safe_send(message) sub = Iq(to_jid=self.config.master, stanza_type="set") query = sub.new_query('http://vipadia.com/skype', "command") add_child(query, "item", attrs={ "command": "register-available", "jid": frm.as_utf8() }) dbg(" sub:\n%s" % (fmt_evt(sub), )) self.safe_send(sub) reply = "Presence request sent" elif cmd[0].lower() == "register-carrier": if len(cmd) != 3: reply = "error, please use: register <skypeuser> <skypepassword>" skypeuser = cmd[1] ## KeyCzar ## crypter = keyczar.Encrypter.Read(PUBLIC_KEYLOC) skypesecret = cmd[2] ## KeyCzar ## skypesecret = crypter.Encrypt(str(skypesecret)) spawn = Iq(to_jid=self.config.master, stanza_type="set") command = spawn.new_query("http://vipadia.com/skype", "command") add_child(command, "item", attrs={ "command": "spawn", "ujid": frm.as_utf8(), "skypeuser": skypeuser, "skypesecret": skypesecret, }) self.safe_send(spawn) elif cmd[0].lower() == "unregister": if len(cmd) == 1: RegDB.remove_credentials(user) reply = "Unregistration successful" else: reply = "Skype Registration Commands:\r\n" + \ " register <skypeuser> <skypepass>\r\n" + \ " unregister" message = Message(to_jid=stanza.get_from(), body=reply) self.safe_send(message) return True # # presence handlers # def subscription(self, stanza): dbg("subscription:\n%s" % (fmt_evt(stanza), ), 3) send_response = not (stanza.get_type() == 'subscribed') if send_response: self.safe_send(stanza.make_accept_response()) return True # # iq handlers # def vipadia_command(self, iq): dbg("vipadia_command:\n%s" % (fmt_evt(iq), )) items = iq.xpath_eval("v:command/v:item", { "v": "http://vipadia.com/skype", }) for item in items: command = item.prop("command") if command == "message": ujid = JID(item.prop("ujid")) message = item.prop("message") dbg(" +ujid:%s precedingmessage:%s" % ( ujid.as_utf8(), PrecedingMessage, )) if ujid in PrecedingMessage and PrecedingMessage[ ujid] == message: continue PrecedingMessage[ujid] = message self.safe_send(Message(to_jid=ujid, body=message)) dbg(" -ujid:%s precedingmessage:%s" % ( ujid.as_utf8(), PrecedingMessage, )) return True
def vipadia_command(self, iq): dbg("vipadia_command:\n%s" % (fmt_evt(iq), )) StLock.acquire() try: items = iq.xpath_eval("v:command/v:item", { "v": "http://vipadia.com/skype", }) for item in items: command = item.prop("command") if command == "subscribe": djid = JID(item.prop("djid")) if djid not in St['dialbacks']: self.safe_send(iq.make_result_response()) return True self.safe_send( Presence(to_jid=St['dialbacks'][djid], from_jid=item.prop("from"), stanza_type="subscribe")) elif command == "subscribed": frm = JID("%s@%s" % (item.prop("from"), self.config.component)) ujid = St['dialbacks'][get_from(iq)] self.safe_send( Presence(to_jid=ujid, from_jid=frm, stanza_type="subscribed")) elif command == "register-subscribe": jid = JID(item.prop("jid")) self.safe_send( Presence(to_jid=jid.bare(), from_jid=self.config.component, stanza_type="subscribe")) elif command == "register-available": jid = JID(item.prop("jid")) fake_available = Presence(to_jid=self.config.component, from_jid=jid) self.presence_available(fake_available) elif command == "out-subscribe": frm = JID("%s@%s" % (item.prop("from"), self.config.component)) iq_frm = get_from(iq) if iq_frm not in St['dialbacks']: self.safe_send(iq.make_result_response()) return True ujid = St['dialbacks'][iq_frm] self.safe_send( Presence(to_jid=ujid, from_jid=frm, stanza_type="subscribe")) elif command == "slave-online": frm = get_from(iq) digest = str(item.prop("digest")) if not self.is_valid_slave(frm.as_utf8(), digest): err("invalid slave! frm:%s iq:\n%s" % (frm.as_utf8(), fmt_evt(iq))) self.safe_send(iq.make_error_response("forbidden")) return True capacity = int(item.prop("capacity")) base = int(item.prop("base")) St['slaves'][frm] = None St['slots'][frm] = {} dbg(" before St['slots']:%s" % (St['slots'], )) for i in range(base, base + capacity): if i not in St['slots'][frm]: St['slots'][frm][i] = None dbg(" after St['slots']:%s" % (St['slots'], )) self.safe_send( Presence(to_jid=frm, from_jid=self.config.component, stanza_type="subscribe")) elif command == "spawn": ujid = item.prop("ujid") skypeuser = item.prop("skypeuser") skypesecret = item.prop("skypesecret") errstr = self._spawn(JID(ujid), skypeuser, skypesecret) if errstr: err("_spawn error! errstr:%s" % (errstr, )) else: err("unknown command! command:%s\n%s" % ( command, fmt_evt(iq), )) self.safe_send( iq.make_error_response("feature-not-implemented")) return True self.safe_send(iq.make_result_response()) return True finally: StLock.release()