def handle(self): # first send the info message self.authrand = authrand = os.urandom(4) log.debug("Authentication starting for: {0}".format(self.addr)) self.write(proto.msginfo(config.FBNAME, authrand)) self.mandatory_authentication() while True: opcode, ident, data = self.read_message() if not ident == self.ak: self.error("Invalid authkey in message.", ident=ident) log.critical( "Invalid authkey in message from: {0}".format(ident)) raise BadClient() if opcode == proto.OP_PUBLISH: chan, payload = proto.split(data, 1) if not self.may_publish(chan) or chan.endswith("..broker"): self.error("Authkey not allowed to publish here.", chan=chan) log.critical( "Authkey not allowed ot publish here: {0}".format( chan)) continue self.srv.do_publish(self, chan, payload) elif opcode == proto.OP_SUBSCRIBE: chan = data checkchan = chan if chan.endswith('..broker'): checkchan = chan.rsplit('..broker', 1)[0] if not self.may_subscribe(checkchan): self.error("Authkey not allowed to subscribe here.", chan=chan) log.critical( "Authkey not allowed ot publish here: {0}".format( chan)) continue self.srv.do_subscribe(self, ident, chan) elif opcode == proto.OP_UNSUBSCRIBE: chan = data self.do_unsubscribe(self, ident, chan) else: self.error("Unknown message type.", opcode=opcode, length=len(data)) log.critical("Unknown message type: {0}".format(opcode)) raise BadClient()
def handle(self): # first send the info message self.authrand = authrand = os.urandom(4) self.write(proto.msginfo(config.FBNAME, authrand)) self.mandatory_authentication() self.statgreenlet = gevent.spawn(self.periodic_stats) while True: opcode, ident, data = self.read_message() if not ident == self.ak: self.error("Invalid authkey in message.", ident=ident) raise BadClient() if opcode == proto.OP_PUBLISH: chan, payload = proto.split(data, 1) if not self.may_publish(chan) or chan.endswith("..broker"): self.error("Authkey not allowed to publish here.", chan=chan) continue self.srv.do_publish(self, chan, payload) self.stats["published"] += 1 elif opcode == proto.OP_SUBSCRIBE: chan = data checkchan = chan if chan.endswith('..broker'): checkchan = chan.rsplit('..broker', 1)[0] if not self.may_subscribe(checkchan): self.error("Authkey not allowed to subscribe here.", chan=chan) continue self.srv.do_subscribe(self, ident, chan) elif opcode == proto.OP_UNSUBSCRIBE: chan = data self.do_unsubscribe(self, ident, chan) else: self.error("Unknown message type.", opcode=opcode, length=len(data)) raise BadClient()
def authkey_check(self, ident, rhash): akrow = self.srv.get_authkey(ident) if not akrow: self.error("Authentication failed.", ident=ident) raise BadClient() akhash = utils.hash(self.authrand, akrow["secret"]) if not akhash == rhash: self.error("Authentication failed.", ident=ident) raise BadClient() self.ak = ident self.uid = akrow["owner"] self.pubchans = akrow.get("pubchans", []) self.subchans = akrow.get("subchans", [])
def mandatory_authentication(self): opcode, ident, rhash = self.read_message() if not opcode == proto.OP_AUTH: self.error("First message was not AUTH.") raise BadClient() self.authkey_check(ident, rhash)
def read_message(sock): buf = recv(sock, 5) ml, opcode = struct.unpack('!iB', buf) if ml > MAXBUF: logging.critical("Client not respecting MAXBUF: {0}".format( sock.getpeername())) raise BadClient() buf = recv(sock, ml - 5) nextlen, buf = ord(buf[0]), buf[1:] ident, buf = buf[:nextlen], buf[nextlen:] return opcode, ident, buf