def get_table4_record(self, action): if self.rawtables is None or "4" not in self.rawtables: return '' else: pay = self.rawtables["4"] lenrec = struct.unpack('<H', pay[28:30])[0] record = pay[30:30 + lenrec] if action.name is None: nm = None elif len(action.name) > 16: nm = action.name[0:16] else: nm = action.name.ljust(16) if nm is not None: record = record[0:40] + s2b(nm) + record[56:] if action.ip is not None: record = record[0:118] + s2b( DeviceUDP.ip2string(action.ip) + DeviceUDP.ip2string(action.gateway) + DeviceUDP.ip2string( action.nmask)) + b'\x00\x01' + record[132:] if action.timezone is not None: record = record[0:132] + ( b'\x01\x00' if action.timezone == DeviceUDP.TIMEZONE_NOT_SET else b'\x00' + struct.pack('<b', action.timezone)) + record[134:] if action.timer_off_after_on is not None: record = record[0:134] + ( b'\x00\xff' if action.timer_off_after_on <= 0 else b'\x01\x00') + struct.pack( '<H', action.timer_off_after_on) + record[138:] return record
def get_send_bytes(jsono, convid, key=PK_KEY, typemsg="dk"): try: if convid is None: convid = generatestring(32) if 'serial' in jsono and jsono['serial'] is None: jsono['serial'] = SendBufferTimer.get_serial() if 'key' in jsono and jsono['key'] is None: jsono['key'] = generatestring(16) msg = s2b(json.dumps(jsono)) _LOGGER.info("Encrypting with %s MSG %s" % (b2s(key), b2s(msg))) lnmsg = len(msg) remain = lnmsg % 16 if remain > 0: remain = (lnmsg // 16) * 16 + 16 - lnmsg msg += b"\x20" * remain ln = lnmsg + remain + 4 + 2 + 2 + 2 + 32 cry = AES.new(s2b(key), AES.MODE_ECB) newbytes = cry.encrypt(msg) crc32 = binascii.crc32(newbytes) bytesa = MAGIC + struct.pack('>H', ln) + typemsg + \ struct.pack('>i', crc32) + s2b(convid) return bytesa + newbytes except: # noqa: E722 _LOGGER.warning(f"{traceback.format_exc()}") return b''
def dowrite(self, addr): snd = b'' self.cond.acquire() keyv = '{}:{}'.format(*addr) if not self.stopped and keyv in self.clientinfo and keyv in self.towrite: while len(snd) == 0 and len(self.towrite[keyv]) > 0: snd = self.towrite[keyv][0] if isinstance(snd, (bytes, str)): snd = s2b(self.towrite[keyv].pop(0)) # _LOGGER.info("01_1") elif snd.timer is not None: # dobbiamo aspettare la risposta snd = b'' # _LOGGER.info("01_2") break elif snd.has_succeeded() or snd.has_failed(): if "sender" in self.clientinfo[keyv]: del self.clientinfo[keyv]['sender'] if snd.has_failed(): self.clientinfo[keyv]['disconnecttimer'] = time.time() self.towrite[keyv].pop(0) snd = b'' # _LOGGER.info("01_3") else: # dobbiamo ancora spedire il pacchetto o c'e gia stato un timeout ma dobbiamo fare altri tentativi snd.clientinfo = self.clientinfo[keyv] self.clientinfo[keyv]['sender'] = snd snd = snd.schedule() # _LOGGER.info("01_4") self.cond.release() return snd
def get_state_http(self, timeout): now = time.time() if now - self.last_get > 10: r = requests.post('http://{}:{}/cgi-bin/web.cgi'.format( self.host, self.port), data={ 'tk': self.tk, 'qindex': self.qindex, 'mod': 'cmd' }, timeout=timeout) lst = r.json()['cmd'] _LOGGER.info( f'Get state (difftime = {now - self.last_get}) rv = {lst}') rv = None self.last_get = now for d in lst: idv = d['id'] if idv == str(self.id): rv = DevicePrimelan.http_state_to_real_state(d) else: event.EventManager.fire( eventname='ExtChangeState', hp=(self.host, self.port), mac=s2b(DevicePrimelan.generate_mac(self.host, idv)), newstate=DevicePrimelan.http_state_to_real_state(d)) else: rv = self.state return rv
def write_response_base(self, obj): self.protocol_version = 'HTTP/1.1' if 'action' in obj and obj['action'] is not None: self.send_response(200, 'OK') else: self.send_response(403, 'Forbidden') self.send_header('Content-type', 'application/json') self.end_headers() self.wfile.write(s2b(json.dumps(obj)))
def handle_incoming_data(data, key=PK_KEY): try: valasci = binascii.crc32(data[42:]) _LOGGER.info( f"K={b2s(key)} Computed CRC %08X vs {tohexs(data[6:10])}" % valasci) if valasci == struct.unpack('>i', data[6:10])[0]: cry = AES.new(s2b(key), AES.MODE_ECB) msg = cry.decrypt(data[42:]) _LOGGER.info("Decrypted MSG %s" % b2s(msg)) jsono = json.loads(msg[0:msg.rfind(b'}') + 1]) return {'msg': jsono, 'convid': b2s(data[10:42])} except: # noqa: E722 _LOGGER.warning(f"{traceback.format_exc()}") pass return None
def __init__(self, hp=('', 0), mac='', root=None, name='', idv=0, typev=0, tk='', qindex=0, passw='', port2=6004, state=0): nn = DevicePrimelan.generate_name_nick(name) nick = nn[1] name = nn[0] Device.__init__(self, hp, mac, root, name) self.oldstate = "0" self.last_get = -1 if root is not None: self.id = root.attributes['id'].value self.subtype = int(root.attributes['subtype'].value) self.tk = root.attributes['tk'].value self.qindex = root.attributes['qindex'].value self.nick = root.attributes['nick'].value self.passw = root.attributes['passw'].value self.port2 = int(root.attributes['port2'].value) self.state = "0" else: self.id = idv self.subtype = int(typev) self.tk = tk self.qindex = qindex self.state = str(state) self.nick = nick self.passw = passw self.port2 = port2 self.key = s2b(self.passw) + (b'\x00' * (16 - len(self.passw))) self.iv = reduce(lambda x, y: x + struct.pack("<B", y[1] ^ y[0]), enumerate(self.key), b'')
def __init__(self, hp=('', 0), mac='', root=None, name='', **kw): if root is None: self.host = hp[0] self.port = hp[1] self.mac = s2b(mac) self.name = self.default_name() if not len(name) else name self.offlimit = 60 else: self.host = root.attributes['host'].value self.port = int(root.attributes['port'].value) self.mac = bfromhex(root.attributes['mac'].value) self.name = root.attributes['name'].value try: self.offlimit = int(root.attributes['offlimit'].value) except: # noqa: E722 _LOGGER.warning(f"{traceback.format_exc()}") self.offlimit = 60 self.timers = None self.offt = 0 self.mqtt_client = None self.mqtt_userdata = None self.mqtt_topic_retain = dict()
def apop_hash ( challenge: str, pwd: str ) -> str: # TODO FIXME: is this in the email library already maybe? return hashlib.md5 ( s2b ( f'{challenge}{pwd}' ) ).hexdigest()
def ResponseEvent ( ok: bool, text: str ) -> SendDataEvent: ok_ = '+OK' if ok else '-ERR' data = s2b ( f'{ok_} {text}\r\n' ) return SendDataEvent ( data )
def ResponseEvent(code: int, *lines: str) -> SendDataEvent: seps = ['-'] * len(lines) seps[-1] = ' ' chunks = (s2b(''.join(f'{code}{sep}{line}\r\n' for sep, line in zip(seps, lines))), ) return SendDataEvent(*chunks)
def send ( self, line: str ) -> Iterator[Event]: assert line.endswith ( '\r\n' ), f'invalid {line=}' yield from ( event := SendDataEvent ( s2b ( line ) ) ).go()