core: implement auto-lock after a configurable timeout (fixes #75)

pull/971/head
matejcik 4 years ago committed by matejcik
parent 67b723e4ca
commit 4035aad51b

@ -187,3 +187,5 @@ def boot() -> None:
wire.register(MessageType.Cancel, handle_Cancel) wire.register(MessageType.Cancel, handle_Cancel)
wire.register(MessageType.LockDevice, handle_LockDevice) wire.register(MessageType.LockDevice, handle_LockDevice)
wire.register(MessageType.Ping, handle_Ping) wire.register(MessageType.Ping, handle_Ping)
workflow.idle_timer.set(storage.device.get_autolock_delay_ms(), lock_device)

@ -1,19 +1,24 @@
import storage.device import storage.device
from trezor import ui, wire from trezor import ui, wire, workflow
from trezor.messages import ButtonRequestType from trezor.messages import ButtonRequestType
from trezor.messages.Success import Success from trezor.messages.Success import Success
from trezor.ui.text import Text from trezor.ui.text import Text
from apps.base import lock_device
from apps.common.confirm import require_confirm from apps.common.confirm import require_confirm
if False:
from trezor.messages.ApplySettings import ApplySettings
async def apply_settings(ctx, msg):
async def apply_settings(ctx: wire.Context, msg: ApplySettings):
if ( if (
msg.homescreen is None msg.homescreen is None
and msg.label is None and msg.label is None
and msg.use_passphrase is None and msg.use_passphrase is None
and msg.passphrase_always_on_device is None and msg.passphrase_always_on_device is None
and msg.display_rotation is None and msg.display_rotation is None
and msg.auto_lock_delay_ms is None
): ):
raise wire.ProcessError("No setting provided") raise wire.ProcessError("No setting provided")
@ -36,17 +41,27 @@ async def apply_settings(ctx, msg):
if msg.display_rotation is not None: if msg.display_rotation is not None:
await require_confirm_change_display_rotation(ctx, msg.display_rotation) await require_confirm_change_display_rotation(ctx, msg.display_rotation)
if msg.auto_lock_delay_ms is not None:
msg.auto_lock_delay_ms = max(
msg.auto_lock_delay_ms, storage.device.AUTOLOCK_DELAY_MINIMUM
)
await require_confirm_change_autolock_delay(ctx, msg.auto_lock_delay_ms)
storage.device.load_settings( storage.device.load_settings(
label=msg.label, label=msg.label,
use_passphrase=msg.use_passphrase, use_passphrase=msg.use_passphrase,
homescreen=msg.homescreen, homescreen=msg.homescreen,
passphrase_always_on_device=msg.passphrase_always_on_device, passphrase_always_on_device=msg.passphrase_always_on_device,
display_rotation=msg.display_rotation, display_rotation=msg.display_rotation,
autolock_delay_ms=msg.auto_lock_delay_ms,
) )
if msg.display_rotation is not None: if msg.display_rotation is not None:
ui.display.orientation(storage.device.get_rotation()) ui.display.orientation(storage.device.get_rotation())
# use the value that was stored, not the one that was supplied by the user
workflow.idle_timer.set(storage.device.get_autolock_delay_ms(), lock_device)
return Success(message="Settings applied") return Success(message="Settings applied")
@ -98,3 +113,10 @@ async def require_confirm_change_display_rotation(ctx, rotation):
text.normal("to") text.normal("to")
text.bold("%s?" % label) text.bold("%s?" % label)
await require_confirm(ctx, text, ButtonRequestType.ProtectCall) await require_confirm(ctx, text, ButtonRequestType.ProtectCall)
async def require_confirm_change_autolock_delay(ctx, delay_ms):
text = Text("Auto-lock delay", ui.ICON_CONFIG, new_lines=False)
text.normal("Do you really want to", "auto-lock your device", "after")
text.bold("{} seconds?".format(delay_ms // 1000))
await require_confirm(ctx, text, ButtonRequestType.ProtectCall)

@ -38,6 +38,8 @@ _DEFAULT_BACKUP_TYPE = BackupType.Bip39
# fmt: on # fmt: on
HOMESCREEN_MAXSIZE = 16384 HOMESCREEN_MAXSIZE = 16384
AUTOLOCK_DELAY_MINIMUM = 10 * 1000 # 10 seconds
AUTOLOCK_DELAY_DEFAULT = 10 * 60 * 1000 # 10 minutes
# Length of SD salt auth tag. # Length of SD salt auth tag.
# Other SD-salt-related constants are in sd_salt.py # Other SD-salt-related constants are in sd_salt.py
@ -159,6 +161,7 @@ def load_settings(
homescreen: bytes = None, homescreen: bytes = None,
passphrase_always_on_device: bool = None, passphrase_always_on_device: bool = None,
display_rotation: int = None, display_rotation: int = None,
autolock_delay_ms: int = None,
) -> None: ) -> None:
if use_passphrase is False: if use_passphrase is False:
passphrase_always_on_device = False passphrase_always_on_device = False
@ -185,6 +188,8 @@ def load_settings(
common.set( common.set(
_NAMESPACE, _ROTATION, display_rotation.to_bytes(2, "big"), True _NAMESPACE, _ROTATION, display_rotation.to_bytes(2, "big"), True
) # public ) # public
if autolock_delay_ms is not None:
set_autolock_delay_ms(autolock_delay_ms)
def get_flags() -> int: def get_flags() -> int:
@ -209,14 +214,13 @@ def set_flags(flags: int) -> None:
def get_autolock_delay_ms() -> int: def get_autolock_delay_ms() -> int:
b = common.get(_NAMESPACE, _AUTOLOCK_DELAY_MS) b = common.get(_NAMESPACE, _AUTOLOCK_DELAY_MS)
if b is None: if b is None:
return 10 * 60 * 1000 return AUTOLOCK_DELAY_DEFAULT
else: else:
return int.from_bytes(b, "big") return int.from_bytes(b, "big")
def set_autolock_delay_ms(delay_ms: int) -> None: def set_autolock_delay_ms(delay_ms: int) -> None:
if delay_ms < 60 * 1000: delay_ms = max(delay_ms, AUTOLOCK_DELAY_MINIMUM)
delay_ms = 60 * 1000
common.set(_NAMESPACE, _AUTOLOCK_DELAY_MS, delay_ms.to_bytes(4, "big")) common.set(_NAMESPACE, _AUTOLOCK_DELAY_MS, delay_ms.to_bytes(4, "big"))

Loading…
Cancel
Save