core: add SD format dialog, generalize sdcard usage

pull/858/head
matejcik 4 years ago
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…
Cancel
Save