def setUp(self): self.loop = pyev.Loop() self.keyobj = security.get_keyobj( pem=resource_string("fluxmonitor", "data/test/private_1.pem")) keyobj = security.get_keyobj( der=resource_string("fluxmonitor", "data/test/public_1.pem")) security.add_trusted_keyobj(keyobj=keyobj) self.access_id = security.get_access_id(keyobj=keyobj)
def request__enable_ssh(cls, salt, signature): pem = resource_string("fluxmonitor", "data/develope.pem") rsakey = get_keyobj(pem=pem) if rsakey.verify(salt, a2b_base64(signature)): from fluxmonitor.diagnosis.usb2device import enable_ssh ret = enable_ssh() if ret != 0: raise RuntimeError("EXEC_ERROR_%s" % ret) else: raise RuntimeError("SIGNATURE_ERROR")
def test_pubkey_trust(self): keyobj = security.get_keyobj(der=PUBLICKEY_1) assert keyobj access_id = security.get_access_id(keyobj=keyobj) self.assertFalse(security.is_trusted_remote(der=PUBLICKEY_1)) self.assertFalse(security.is_trusted_remote(keyobj=keyobj)) self.assertFalse(security.is_trusted_remote(access_id=access_id)) security.add_trusted_keyobj(keyobj) self.assertTrue(security.is_trusted_remote(der=PUBLICKEY_1)) self.assertTrue(security.is_trusted_remote(keyobj=keyobj)) self.assertTrue(security.is_trusted_remote(access_id=access_id))
def _on_handshake_identify(self, data): if len(data) >= 20: access_id = to_hex(data[:20]) if access_id == "0" * 40: raise RuntimeError("Not implement") else: self.access_id = access_id self.logger.debug("Access ID: %s" % access_id) self.keyobj = get_keyobj(access_id=access_id) if self.keyobj: if len(data) >= (20 + self.keyobj.size()): self._on_handshake_validate(data) else: self._reply_handshake(AUTH_ERROR, success=False, log_message="Unknow Access ID")
def _on_handshake_identify(self, watcher, revent): try: buf = self.sock.recv(4096) if buf: watcher.data += buf if len(watcher.data) > 20 and not self.access_id: aid = to_hex(watcher.data[:20]) if is_trusted_remote(aid): self.access_id = aid self.remotekey = get_keyobj(access_id=aid) else: logger.debug("Unknown access id") self.sock.send(MESSAGE_AUTH_ERROR) self.on_error() return length = 20 + self.remotekey.size() if len(watcher.data) < length: pass elif len(watcher.data) == length: document = hash_password(UUID_BIN, self.randbytes) if self.remotekey.verify( document, watcher.data[20:length]) or True: # no verify now because fluxclient has bug logger.debug("Connected with access id: %s", self.access_id) self.sock.send(MESSAGE_OK) self.on_authorized() else: self.sock.send(AUTH_ERROR) self.on_error() else: logger.debug("SSL server handshake protocol error") self.sock.send(MESSAGE_PROTOCOL_ERROR) self.on_error() else: logger.debug("Connection closed") self.close() except IOError as e: if e.errno != EAGAIN: logger.debug("SSL server handshake error %r", e) self.on_error() except Exception: logger.exception("SSL server handshake error") self.on_error()
def on_auth(self, buf): """ If auth without password, message will be pem format RSA key. If auth with password, message comes with 'PASSWORD' prefix, the message will be PASSWORD[your password]\\x00[pem format RSA key] """ if buf.startswith(b"PASSWORD"): try: pwd, pem = buf[8:].split("\x00", 1) except ValueError: logger.error("Unpack password in on_auth error") pwd, pem = "", buf else: pwd, pem = "", buf keyobj = security.get_keyobj(pem=pem) if keyobj: if security.is_trusted_remote(keyobj=keyobj): self.send_response(REQ_AUTH, True, b"ALREADY_TRUSTED") else: if security.has_password(): if security.validate_password(pwd): security.add_trusted_keyobj(keyobj) self.send_response(REQ_AUTH, True, MSG_OK) else: self.send_response(REQ_AUTH, False, b"BAD_PASSWORD") else: security.add_trusted_keyobj(keyobj) self.send_response(REQ_AUTH, True, MSG_OK) else: logger.error("Get bad rsa key: %s" % pem.decode("ascii", "ignore")) self.send_response( REQ_AUTH, False, b"BAD_KEY", )
def aws_on_request_callback(self, client, userdata, message): # incommint topic format: "device/{token}/request/{action}" # response topic format: "device/{token}/response/{action}" action = message.topic.split("/", 3)[-1] logger.debug("IoT request: %s", action) response_topic = "device/%s/response/%s" % (self.aws_token, action) try: payload = json.loads(message.payload) except ValueError: logger.error("IoT request payload error: %s", message.payload) client.publish(response_topic, message.payload) return if payload.get("uuid") != self.uuidhex: client.publish( response_topic, json.dumps({ "status": "reject", "cmd_index": payload.get("cmd_index") })) return cmd_index = payload.get("cmd_index") try: if action == "getchu": try: current_hash = metadata.cloud_hash access_id, signature = payload.get("validate_message") client_key = security.get_keyobj(access_id=access_id) if client_key.verify(current_hash, a2b_base64(signature)): client.publish( response_topic, json.dumps({ "status": "ok", "cmd_index": cmd_index })) else: client.publish( response_topic, json.dumps({ "status": "reject", "cmd_index": cmd_index })) finally: metadata.cloud_hash = os.urandom(32) elif action == "monitor": self._notify_aggressive = time() + 180 self._notify_last_st["st_id"] = None client.publish( response_topic, json.dumps({ "status": "ok", "cmd_index": cmd_index })) elif action == "camera": self.require_camera(payload["camera_id"], payload["endpoint"], payload["token"]) client.publish( response_topic, json.dumps({ "status": "ok", "cmd_index": cmd_index })) elif action == "control": self.require_control(payload["endpoint"], payload["token"]) client.publish( response_topic, json.dumps({ "status": "ok", "cmd_index": cmd_index })) else: client.publish( response_topic, json.dumps({ "status": "error", "cmd_index": cmd_index })) except Exception: logger.exception("Handle aws request error") client.publish( response_topic, json.dumps({ "status": "error", "cmd_index": cmd_index }))