mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-02-24 05:12:02 +00:00
core: add SD format dialog, generalize sdcard usage
This commit is contained in:
parent
5bac85f260
commit
1e9352b9e0
@ -78,8 +78,8 @@ async def info_confirm(
|
|||||||
|
|
||||||
|
|
||||||
async def hold_to_confirm(
|
async def hold_to_confirm(
|
||||||
ctx: wire.Context,
|
ctx: wire.GenericContext,
|
||||||
content: ui.Layout,
|
content: ui.Component,
|
||||||
code: EnumTypeButtonRequestType = ButtonRequestType.Other,
|
code: EnumTypeButtonRequestType = ButtonRequestType.Other,
|
||||||
confirm: str = HoldToConfirm.DEFAULT_CONFIRM,
|
confirm: str = HoldToConfirm.DEFAULT_CONFIRM,
|
||||||
confirm_style: ButtonStyleType = HoldToConfirm.DEFAULT_CONFIRM_STYLE,
|
confirm_style: ButtonStyleType = HoldToConfirm.DEFAULT_CONFIRM_STYLE,
|
||||||
|
@ -7,7 +7,7 @@ from trezor.ui.pin import CANCELLED, PinDialog
|
|||||||
from trezor.ui.popup import Popup
|
from trezor.ui.popup import Popup
|
||||||
from trezor.ui.text import Text
|
from trezor.ui.text import Text
|
||||||
|
|
||||||
from apps.common.sd_salt import SdProtectCancelled, request_sd_salt
|
from apps.common.sdcard import SdCardUnavailable, request_sd_salt
|
||||||
|
|
||||||
if False:
|
if False:
|
||||||
from typing import Any, Optional, Tuple
|
from typing import Any, Optional, Tuple
|
||||||
@ -95,7 +95,7 @@ async def verify_user_pin(
|
|||||||
) -> None:
|
) -> None:
|
||||||
try:
|
try:
|
||||||
salt = await request_sd_salt()
|
salt = await request_sd_salt()
|
||||||
except SdProtectCancelled:
|
except SdCardUnavailable:
|
||||||
raise PinCancelled
|
raise PinCancelled
|
||||||
|
|
||||||
if not config.has_pin() and not config.check_pin(pin_to_int(""), salt):
|
if not config.has_pin() and not config.check_pin(pin_to_int(""), salt):
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
import storage.sd_salt
|
import storage.sd_salt
|
||||||
from storage.sd_salt import SD_CARD_HOT_SWAPPABLE
|
from storage.sd_salt import SD_CARD_HOT_SWAPPABLE
|
||||||
from trezor import io, ui, wire
|
from trezor import sdcard, ui, wire
|
||||||
from trezor.ui.text import Text
|
from trezor.ui.text import Text
|
||||||
|
|
||||||
from apps.common.confirm import confirm
|
from apps.common.confirm import confirm, hold_to_confirm
|
||||||
|
|
||||||
if False:
|
if False:
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
|
|
||||||
class SdProtectCancelled(wire.ProcessError):
|
class SdCardUnavailable(wire.ProcessError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
@ -45,17 +45,57 @@ async def insert_card_dialog(ctx: wire.GenericContext) -> bool:
|
|||||||
return await confirm(ctx, text, confirm=btn_confirm, cancel=btn_cancel)
|
return await confirm(ctx, text, confirm=btn_confirm, cancel=btn_cancel)
|
||||||
|
|
||||||
|
|
||||||
|
async def format_card_dialog(ctx: wire.GenericContext) -> bool:
|
||||||
|
# Format card? yes/no
|
||||||
|
text = Text("SD card error", ui.ICON_WRONG, ui.RED)
|
||||||
|
text.bold("Unknown filesystem.")
|
||||||
|
text.br_half()
|
||||||
|
text.normal("Use a different card or")
|
||||||
|
text.normal("format the SD card to")
|
||||||
|
text.normal("the FAT32 filesystem.")
|
||||||
|
if not await confirm(ctx, text, confirm="Format", cancel="Cancel"):
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Confirm formatting
|
||||||
|
text = Text("Format SD card", ui.ICON_WIPE, ui.RED)
|
||||||
|
text.normal("Do you really want to", "format the SD card?")
|
||||||
|
text.br_half()
|
||||||
|
text.bold("All data on the SD card", "will be lost.")
|
||||||
|
return await hold_to_confirm(ctx, text, confirm="Format SD card")
|
||||||
|
|
||||||
|
|
||||||
async def sd_problem_dialog(ctx: wire.GenericContext) -> bool:
|
async def sd_problem_dialog(ctx: wire.GenericContext) -> bool:
|
||||||
text = Text("SD card protection", ui.ICON_WRONG, ui.RED)
|
text = Text("SD card problem", ui.ICON_WRONG, ui.RED)
|
||||||
text.normal("There was a problem", "accessing the SD card.")
|
text.normal("There was a problem", "accessing the SD card.")
|
||||||
return await confirm(ctx, text, confirm="Retry", cancel="Abort")
|
return await confirm(ctx, text, confirm="Retry", cancel="Abort")
|
||||||
|
|
||||||
|
|
||||||
async def ensure_sd_card(ctx: wire.GenericContext) -> None:
|
async def ensure_sdcard(ctx: wire.GenericContext) -> None:
|
||||||
sd = io.SDCard()
|
while not sdcard.is_present():
|
||||||
while not sd.present():
|
|
||||||
if not await insert_card_dialog(ctx):
|
if not await insert_card_dialog(ctx):
|
||||||
raise SdProtectCancelled("SD card required.")
|
raise SdCardUnavailable("SD card required.")
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
with sdcard.get_filesystem(mounted=False) as fs:
|
||||||
|
fs.mount()
|
||||||
|
# Mount succeeded, filesystem is OK
|
||||||
|
return
|
||||||
|
except OSError:
|
||||||
|
# Mount failed. Handle the problem outside except-clause
|
||||||
|
pass
|
||||||
|
|
||||||
|
if not await format_card_dialog(ctx):
|
||||||
|
raise SdCardUnavailable("SD card not formatted.")
|
||||||
|
|
||||||
|
try:
|
||||||
|
with sdcard.get_filesystem(mounted=False) as fs:
|
||||||
|
fs.mkfs()
|
||||||
|
# mkfs succeeded. Re-run loop to retry mounting.
|
||||||
|
continue
|
||||||
|
except OSError:
|
||||||
|
if not await sd_problem_dialog(ctx):
|
||||||
|
raise SdCardUnavailable("Problem formatting SD card.")
|
||||||
|
|
||||||
|
|
||||||
async def request_sd_salt(
|
async def request_sd_salt(
|
||||||
@ -65,16 +105,15 @@ async def request_sd_salt(
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
await ensure_sd_card(ctx)
|
await ensure_sdcard(ctx)
|
||||||
try:
|
try:
|
||||||
return storage.sd_salt.load_sd_salt()
|
return storage.sd_salt.load_sd_salt()
|
||||||
except storage.sd_salt.WrongSdCard:
|
except storage.sd_salt.WrongSdCard:
|
||||||
if not await _wrong_card_dialog(ctx):
|
if not await _wrong_card_dialog(ctx):
|
||||||
raise SdProtectCancelled("Wrong SD card.")
|
raise SdCardUnavailable("Wrong SD card.")
|
||||||
except OSError:
|
except OSError:
|
||||||
# Either the SD card did not power on, or the filesystem could not be
|
# Generic problem with loading the SD salt (either we could not read the
|
||||||
# mounted (card is not formatted?), or there is a staged salt file and
|
# file, or there is a staged salt which cannot be committed).
|
||||||
# we could not commit it.
|
|
||||||
# In either case, there is no good way to recover. If the user clicks Retry,
|
# In either case, there is no good way to recover. If the user clicks Retry,
|
||||||
# we will try again.
|
# we will try again.
|
||||||
if not await sd_problem_dialog(ctx):
|
if not await sd_problem_dialog(ctx):
|
@ -3,7 +3,7 @@ import storage.device
|
|||||||
import storage.recovery
|
import storage.recovery
|
||||||
import storage.sd_salt
|
import storage.sd_salt
|
||||||
from storage import cache
|
from storage import cache
|
||||||
from trezor import config, io, utils, wire
|
from trezor import config, sdcard, utils, wire
|
||||||
from trezor.messages import Capability, MessageType
|
from trezor.messages import Capability, MessageType
|
||||||
from trezor.messages.Features import Features
|
from trezor.messages.Features import Features
|
||||||
from trezor.messages.Success import Success
|
from trezor.messages.Success import Success
|
||||||
@ -69,7 +69,7 @@ def get_features() -> Features:
|
|||||||
Capability.ShamirGroups,
|
Capability.ShamirGroups,
|
||||||
Capability.PassphraseEntry,
|
Capability.PassphraseEntry,
|
||||||
]
|
]
|
||||||
f.sd_card_present = io.SDCard().present()
|
f.sd_card_present = sdcard.is_present()
|
||||||
f.sd_protection = storage.sd_salt.is_enabled()
|
f.sd_protection = storage.sd_salt.is_enabled()
|
||||||
f.wipe_code_protection = config.has_wipe_code()
|
f.wipe_code_protection = config.has_wipe_code()
|
||||||
f.session_id = cache.get_session_id()
|
f.session_id = cache.get_session_id()
|
||||||
|
@ -14,7 +14,7 @@ from apps.common.request_pin import (
|
|||||||
request_pin_and_sd_salt,
|
request_pin_and_sd_salt,
|
||||||
show_pin_invalid,
|
show_pin_invalid,
|
||||||
)
|
)
|
||||||
from apps.common.sd_salt import ensure_sd_card, sd_problem_dialog
|
from apps.common.sdcard import ensure_sdcard, sd_problem_dialog
|
||||||
|
|
||||||
if False:
|
if False:
|
||||||
from typing import Awaitable, Tuple
|
from typing import Awaitable, Tuple
|
||||||
@ -32,7 +32,7 @@ async def _set_salt(
|
|||||||
ctx: wire.Context, salt: bytes, salt_tag: bytes, stage: bool = False
|
ctx: wire.Context, salt: bytes, salt_tag: bytes, stage: bool = False
|
||||||
) -> None:
|
) -> None:
|
||||||
while True:
|
while True:
|
||||||
await ensure_sd_card(ctx)
|
await ensure_sdcard(ctx)
|
||||||
try:
|
try:
|
||||||
return storage.sd_salt.set_sd_salt(salt, salt_tag, stage)
|
return storage.sd_salt.set_sd_salt(salt, salt_tag, stage)
|
||||||
except OSError:
|
except OSError:
|
||||||
@ -62,7 +62,7 @@ async def sd_protect_enable(ctx: wire.Context, msg: SdProtect) -> Success:
|
|||||||
await require_confirm_sd_protect(ctx, msg)
|
await require_confirm_sd_protect(ctx, msg)
|
||||||
|
|
||||||
# Make sure SD card is present.
|
# Make sure SD card is present.
|
||||||
await ensure_sd_card(ctx)
|
await ensure_sdcard(ctx)
|
||||||
|
|
||||||
# Get the current PIN.
|
# Get the current PIN.
|
||||||
if config.has_pin():
|
if config.has_pin():
|
||||||
@ -133,7 +133,7 @@ async def sd_protect_refresh(ctx: wire.Context, msg: SdProtect) -> Success:
|
|||||||
await require_confirm_sd_protect(ctx, msg)
|
await require_confirm_sd_protect(ctx, msg)
|
||||||
|
|
||||||
# Make sure SD card is present.
|
# Make sure SD card is present.
|
||||||
await ensure_sd_card(ctx)
|
await ensure_sdcard(ctx)
|
||||||
|
|
||||||
# Get the current PIN and salt from the SD card.
|
# Get the current PIN and salt from the SD card.
|
||||||
pin, old_salt = await request_pin_and_sd_salt(ctx, "Enter PIN")
|
pin, old_salt = await request_pin_and_sd_salt(ctx, "Enter PIN")
|
||||||
|
@ -5,7 +5,7 @@ from trezor import config, log, loop, res, ui, utils
|
|||||||
from trezor.pin import pin_to_int, show_pin_timeout
|
from trezor.pin import pin_to_int, show_pin_timeout
|
||||||
|
|
||||||
from apps.common.request_pin import PinCancelled, request_pin
|
from apps.common.request_pin import PinCancelled, request_pin
|
||||||
from apps.common.sd_salt import SdProtectCancelled, request_sd_salt
|
from apps.common.sdcard import SdCardUnavailable, request_sd_salt
|
||||||
|
|
||||||
|
|
||||||
async def bootscreen() -> None:
|
async def bootscreen() -> None:
|
||||||
@ -31,7 +31,7 @@ async def bootscreen() -> None:
|
|||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
label = "Wrong PIN, enter again"
|
label = "Wrong PIN, enter again"
|
||||||
except (OSError, PinCancelled, SdProtectCancelled) as e:
|
except (OSError, PinCancelled, SdCardUnavailable) as e:
|
||||||
if __debug__:
|
if __debug__:
|
||||||
log.exception(__name__, e)
|
log.exception(__name__, e)
|
||||||
except BaseException as e:
|
except BaseException as e:
|
||||||
|
Loading…
Reference in New Issue
Block a user