Exemple #1
0
    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
Exemple #2
0
 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''
Exemple #3
0
    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
Exemple #4
0
 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
Exemple #5
0
 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)))
Exemple #6
0
 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
Exemple #7
0
    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'')
Exemple #8
0
 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()
Exemple #9
0
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()
Exemple #10
0
def ResponseEvent ( ok: bool, text: str ) -> SendDataEvent:
	ok_ = '+OK' if ok else '-ERR'
	data = s2b (
		f'{ok_} {text}\r\n'
	)
	return SendDataEvent ( data )
Exemple #11
0
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)
Exemple #12
0
	def send ( self, line: str ) -> Iterator[Event]:
		assert line.endswith ( '\r\n' ), f'invalid {line=}'
		yield from ( event := SendDataEvent ( s2b ( line ) ) ).go()