예제 #1
0
    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)
예제 #2
0
    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")
예제 #3
0
    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))
예제 #4
0
    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")
예제 #5
0
    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()
예제 #6
0
    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",
            )
예제 #7
0
    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
                }))