mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-02-23 13:02:03 +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(
|
||||
ctx: wire.Context,
|
||||
content: ui.Layout,
|
||||
ctx: wire.GenericContext,
|
||||
content: ui.Component,
|
||||
code: EnumTypeButtonRequestType = ButtonRequestType.Other,
|
||||
confirm: str = HoldToConfirm.DEFAULT_CONFIRM,
|
||||
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.text import Text
|
||||
|
||||
from apps.common.sd_salt import SdProtectCancelled, request_sd_salt
|
||||
from apps.common.sdcard import SdCardUnavailable, request_sd_salt
|
||||
|
||||
if False:
|
||||
from typing import Any, Optional, Tuple
|
||||
@ -95,7 +95,7 @@ async def verify_user_pin(
|
||||
) -> None:
|
||||
try:
|
||||
salt = await request_sd_salt()
|
||||
except SdProtectCancelled:
|
||||
except SdCardUnavailable:
|
||||
raise PinCancelled
|
||||
|
||||
if not config.has_pin() and not config.check_pin(pin_to_int(""), salt):
|
||||
|
@ -1,15 +1,15 @@
|
||||
import storage.sd_salt
|
||||
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 apps.common.confirm import confirm
|
||||
from apps.common.confirm import confirm, hold_to_confirm
|
||||
|
||||
if False:
|
||||
from typing import Optional
|
||||
|
||||
|
||||
class SdProtectCancelled(wire.ProcessError):
|
||||
class SdCardUnavailable(wire.ProcessError):
|
||||
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)
|
||||
|
||||
|
||||
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:
|
||||
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.")
|
||||
return await confirm(ctx, text, confirm="Retry", cancel="Abort")
|
||||
|
||||
|
||||
async def ensure_sd_card(ctx: wire.GenericContext) -> None:
|
||||
sd = io.SDCard()
|
||||
while not sd.present():
|
||||
async def ensure_sdcard(ctx: wire.GenericContext) -> None:
|
||||
while not sdcard.is_present():
|
||||
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(
|
||||
@ -65,16 +105,15 @@ async def request_sd_salt(
|
||||
return None
|
||||
|
||||
while True:
|
||||
await ensure_sd_card(ctx)
|
||||
await ensure_sdcard(ctx)
|
||||
try:
|
||||
return storage.sd_salt.load_sd_salt()
|
||||
except storage.sd_salt.WrongSdCard:
|
||||
if not await _wrong_card_dialog(ctx):
|
||||
raise SdProtectCancelled("Wrong SD card.")
|
||||
raise SdCardUnavailable("Wrong SD card.")
|
||||
except OSError:
|
||||
# Either the SD card did not power on, or the filesystem could not be
|
||||
# mounted (card is not formatted?), or there is a staged salt file and
|
||||
# we could not commit it.
|
||||
# Generic problem with loading the SD salt (either we could not read the
|
||||
# file, or there is a staged salt which cannot be committed).
|
||||
# In either case, there is no good way to recover. If the user clicks Retry,
|
||||
# we will try again.
|
||||
if not await sd_problem_dialog(ctx):
|
@ -3,7 +3,7 @@ import storage.device
|
||||
import storage.recovery
|
||||
import storage.sd_salt
|
||||
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.Features import Features
|
||||
from trezor.messages.Success import Success
|
||||
@ -69,7 +69,7 @@ def get_features() -> Features:
|
||||
Capability.ShamirGroups,
|
||||
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.wipe_code_protection = config.has_wipe_code()
|
||||
f.session_id = cache.get_session_id()
|
||||
|
@ -14,7 +14,7 @@ from apps.common.request_pin import (
|
||||
request_pin_and_sd_salt,
|
||||
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:
|
||||
from typing import Awaitable, Tuple
|
||||
@ -32,7 +32,7 @@ async def _set_salt(
|
||||
ctx: wire.Context, salt: bytes, salt_tag: bytes, stage: bool = False
|
||||
) -> None:
|
||||
while True:
|
||||
await ensure_sd_card(ctx)
|
||||
await ensure_sdcard(ctx)
|
||||
try:
|
||||
return storage.sd_salt.set_sd_salt(salt, salt_tag, stage)
|
||||
except OSError:
|
||||
@ -62,7 +62,7 @@ async def sd_protect_enable(ctx: wire.Context, msg: SdProtect) -> Success:
|
||||
await require_confirm_sd_protect(ctx, msg)
|
||||
|
||||
# Make sure SD card is present.
|
||||
await ensure_sd_card(ctx)
|
||||
await ensure_sdcard(ctx)
|
||||
|
||||
# Get the current 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)
|
||||
|
||||
# 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.
|
||||
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 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:
|
||||
@ -31,7 +31,7 @@ async def bootscreen() -> None:
|
||||
return
|
||||
else:
|
||||
label = "Wrong PIN, enter again"
|
||||
except (OSError, PinCancelled, SdProtectCancelled) as e:
|
||||
except (OSError, PinCancelled, SdCardUnavailable) as e:
|
||||
if __debug__:
|
||||
log.exception(__name__, e)
|
||||
except BaseException as e:
|
||||
|
Loading…
Reference in New Issue
Block a user