diff --git a/README.es-ES.md b/README.es-ES.md index da157bc3..8758307a 100644 --- a/README.es-ES.md +++ b/README.es-ES.md @@ -50,7 +50,7 @@ Los tres comparten el mismo núcleo: | **Release actual** | **v2.11.0** (04/10/2026); el [changelog](CHANGELOG.md) dice qué cambió cada versión. SIMUT salió de beta con la v2.7.0, sobre mediciones: un soak de 8,18 h sin ningún reinicio y 6 de 6 actualizaciones por el aire sin perder nada. | | **Imágenes publicadas** | Cuatro imágenes, cada una en `.uf2` y `.bin`. Para la Pico W: `release` (panel táctil TFT), `alpha` (LCD 16×2 con consola Bluetooth) y `air` (registrador a batería sin pantalla). Para la Pico 2 W (RP2350): `releasetwo`, la release, cuyo `.uf2` lleva su tabla de particiones y cuyo `.bin` arranca a prueba. Junto a ellas van los packs de idioma pt-BR y es-ES y un manifiesto de OTA. Una imagen con otro conjunto de funciones sale del [configurador de build](https://angelointj.github.io/simut/configurador/), y el CI la compila desde `main`; el configurador todavía no compila para la Pico 2 W. | | **Madurez** |
Pela web, o PIN tem sempre de 4 a 8 dígitos, qualquer que seja a política de PIN do aparelho. O aparelho recusa um PIN que outra conta já use.
A página não mostra estas recusas: a gravação continua e a ação recusada não aparece. Um script que grava contas pela interface de programação recebe a lista em rejected (capítulo 26).
08-teclado-alfa.pngscreen pin e escolha de uma conta; política 0-9 A-Z, 1 por tecla; grupo PQRS aberto08-teclado-numerico.pngmenu > Alterar Senha, sessão admin; política de fábrica; tela Novo PIN com três dígitos digitadosUm PIN errado faz o painel mostrar PIN inválido!, tocar o som de erro e distribuir os cartões de novo. Um PIN mais curto que o mínimo da política não chega a ser conferido: o painel mostra PIN muito curto (mín. 4).
+Um PIN errado faz o painel mostrar PIN inválido!, tocar o som de erro e distribuir os cartões de novo. Para identificar, o painel confere qualquer PIN a partir de 4 caracteres, mesmo abaixo do mínimo da política: um PIN assim pode ter sido definido antes de a política mudar, ou pela web. Se ele estiver certo, a conta vai direto para a troca (O PIN de fábrica). Com menos de 4 caracteres, o painel mostra PIN muito curto (mín. 4) e não confere. Até a v2.11.0, um PIN mais curto que o mínimo da política nunca era conferido, e a conta ficava sem o painel.
As tentativas erradas são contadas por conta:
| As duas digitações diferem; o painel volta a Novo PIN | |||||
| PIN muito curto (mín. 4) | -Menos caracteres que o mínimo da política | +PIN muito curto (mín. N) | +Menos caracteres que o mínimo da política, que a mensagem diz no lugar de N. Até a v2.11.0, ela dizia 4 com qualquer mínimo | ||
| PIN inválido! | @@ -4356,7 +4356,11 @@Defina um PIN pelo botão PIN da página Usuários ou no item Usuários do painel | ||||
| PIN muito curto (mín. 4) com um PIN definido pela web | -A política exige mais caracteres que o PIN tem; a web aceita 4 a 8 dígitos sem olhar a política | -Defina o PIN no painel, no item Alterar Senha ou em Usuários | +O painel pede Novo PIN logo depois de um PIN definido pela web | +O PIN é mais curto que o mínimo da política; a web aceita 4 a 8 dígitos sem olhar a política | +Escolha um PIN que siga a política. Até a v2.11.0, o painel recusava esse PIN com PIN muito curto (mín. 4) |
| Um PIN antigo não pode mais ser digitado depois de mudar a política | +A política tirou as letras dos cartões, ou o teto ficou menor que o PIN | +Defina um PIN novo para a conta no item Usuários do painel, na página Usuários ou no console | +|||
| PIN já em uso! | Outra conta tem esse PIN | Escolha outro PIN | |||
| Conta aparece com bloqueado no painel | Seis PINs errados seguidos dessa conta | Reinicie o aparelho ou use outra conta | |||
| Tela vermelha ACESSO BLOQUEADO | 20 PINs errados desde a última entrada certa | Reinicie o aparelho | |||
| Contagem Aguarde N segundos… no teclado | Terceira, quarta ou quinta tentativa errada de uma conta | Espere; a espera vale para qualquer conta nesse período | |||
| O painel pede Novo PIN logo depois de entrar | PIN de fábrica 1234 do admin, ou política de PIN mais exigente |
Escolha um PIN novo que atenda à política | |||
| Depois de mudar a política pela web, a mudança não valeu | A política pela web só vale depois de Salvar e reiniciar | Grave com Salvar e reiniciar, ou mude no painel, que aplica na hora | |||
| Operador conseguiu se dar permissões de painel | No painel, quem tem Usuários concede as três permissões de painel sem ter todas | Dê Usuários só a quem pode ter também as permissões de painel | |||
| Bloqueio de 300 s ao entrar pela web | Nove ou mais senhas erradas seguidas a partir do mesmo computador | Espere a contagem; ela zera numa entrada certa | |||
| Limite de sessões atingido. Tente mais tarde. | Três outras contas com sessão aberta | Feche uma sessão com Sair ou espere 15 min de ociosidade dela | diff --git a/docs/_manual/cap08-contas.md b/docs/_manual/cap08-contas.md index 8f2e47c5..34413800 100644 --- a/docs/_manual/cap08-contas.md +++ b/docs/_manual/cap08-contas.md @@ -201,7 +201,7 @@ O reset troca só a senha. As permissões e o PIN continuam como estavam. Uma se Pela web, o PIN tem sempre de 4 a 8 dígitos, qualquer que seja a política de PIN do aparelho. O aparelho recusa um PIN que outra conta já use. ::: atencao -**Um PIN definido pela web pode não servir no painel.** Com uma política de mínimo acima de 4, um PIN mais curto que o mínimo é aceito pela web, mas o teclado do painel o recusa com **PIN muito curto (mín. 4)** antes de conferir. Com a política de letras ou de mais de 8 caracteres, defina o PIN no painel ([O próprio PIN](#cap-08-proprio-pin)). +**Um PIN definido pela web pode não seguir a política do painel.** Com uma política de mínimo acima de 4, a web aceita um PIN mais curto que o mínimo. Ele identifica a conta no painel, e o painel pede um PIN novo logo em seguida, como na troca obrigatória ([O PIN de fábrica](#cap-08-pin-fabrica)). Até a v2.11.0, o teclado do painel recusava esse PIN com **PIN muito curto (mín. 4)** antes de conferir. Com a política de letras ou de mais de 8 caracteres, defina o PIN no painel ([O próprio PIN](#cap-08-proprio-pin)). ::: ### Motivos de recusa {#cap-08-recusas} @@ -299,7 +299,7 @@ O teclado numérico ordenado, usado para definir um PIN. ### PIN errado e bloqueios {#cap-08-bloqueios} -Um PIN errado faz o painel mostrar **PIN inválido!**, tocar o som de erro e distribuir os cartões de novo. Um PIN mais curto que o mínimo da política não chega a ser conferido: o painel mostra **PIN muito curto (mín. 4)**. +Um PIN errado faz o painel mostrar **PIN inválido!**, tocar o som de erro e distribuir os cartões de novo. Para identificar, o painel confere qualquer PIN a partir de 4 caracteres, mesmo abaixo do mínimo da política: um PIN assim pode ter sido definido antes de a política mudar, ou pela web. Se ele estiver certo, a conta vai direto para a troca ([O PIN de fábrica](#cap-08-pin-fabrica)). Com menos de 4 caracteres, o painel mostra **PIN muito curto (mín. 4)** e não confere. Até a v2.11.0, um PIN mais curto que o mínimo da política nunca era conferido, e a conta ficava sem o painel. As tentativas erradas são contadas por conta: @@ -349,7 +349,7 @@ Qualquer conta identificada troca o próprio PIN pelo item **Alterar Senha** do |---|---| | **PIN salvo!** | Gravado; vale na próxima identificação | | **Os PINs não coincidem!** | As duas digitações diferem; o painel volta a **Novo PIN** | -| **PIN muito curto (mín. 4)** | Menos caracteres que o mínimo da política | +| **PIN muito curto (mín. N)** | Menos caracteres que o mínimo da política, que a mensagem diz no lugar de N. Até a v2.11.0, ela dizia 4 com qualquer mínimo | | **PIN inválido!** | Fora da política | | **PIN já em uso!** | Outra conta já tem esse PIN. Nada é gravado | @@ -388,7 +388,10 @@ Ao mudar um ajuste, o painel corrige os outros para uma combinação possível. **Na web.** Os três campos ficam na seção **Hardware** da página **Configurações**, que exige a permissão **Sistema** ([capítulo 6](#cap-06-hardware)). A dica do tamanho mínimo mostra a faixa permitida, como `4 – 8`. Pela web, a mudança vale com **Aplicar agora**, sem reiniciar (até a v2.9.0, exigia **Salvar e reiniciar**). O log registra o mesmo código 459, com a marca `[web]`. -Quando a política fica mais exigente em qualquer ajuste (mínimo maior, alfabeto menor ou teto menor), toda conta com PIN é marcada para trocá-lo. A conta continua se identificando com o PIN antigo e é levada a **Novo PIN** logo depois ([O PIN de fábrica](#cap-08-pin-fabrica)). Afrouxar a política não marca ninguém. +Quando a política fica mais exigente em qualquer ajuste (mínimo maior, alfabeto menor ou teto menor), toda conta com PIN é marcada para trocá-lo, e é levada a **Novo PIN** logo depois de se identificar ([O PIN de fábrica](#cap-08-pin-fabrica)). Afrouxar a política não marca ninguém. + +- **Mínimo maior:** a conta se identifica com o PIN antigo, mesmo mais curto que o mínimo novo. Até a v2.11.0, o teclado recusava esse PIN como curto, e a conta ficava sem o painel. +- **Alfabeto menor ou teto menor:** um PIN antigo com uma letra que saiu dos cartões, ou mais longo que o teto novo, não pode mais ser digitado: o teto não sobe para um PIN antigo, porque é o tempo de conferir. Defina um PIN novo para essa conta no item **Usuários** do painel, na página **Usuários** da web ou no console. ::: {.figura #fig-08-politica tipo="tft" arquivo="08-politica.png" captura="menu > Segurança do PIN, sessão admin; política de fábrica; linha Teclado selecionada"} A tela Segurança do PIN, com a política de fábrica: tamanho mínimo 4, 3 caracteres por tecla (máximo 8) e só dígitos. diff --git a/docs/_manual/cap30-solucao.md b/docs/_manual/cap30-solucao.md index 777981b6..d4408433 100644 --- a/docs/_manual/cap30-solucao.md +++ b/docs/_manual/cap30-solucao.md @@ -139,7 +139,8 @@ Detalhes no [capítulo 8](#cap-08). | Entro na web e vejo só `Access Denied` | A conta não tem a permissão **Painel** | Digite o endereço de uma página permitida, ou recrie a conta com **Painel** | | Backup e atualização de firmware recusados para uma conta com todas as permissões | Essas ações exigem o nível de administrador completo | Use a conta `admin` | | Minha conta não aparece em **Quem está usando o painel?** | A conta não tem PIN | Defina um PIN pelo botão **PIN** da página **Usuários** ou no item **Usuários** do painel | -| **PIN muito curto (mín. 4)** com um PIN definido pela web | A política exige mais caracteres que o PIN tem; a web aceita 4 a 8 dígitos sem olhar a política | Defina o PIN no painel, no item **Alterar Senha** ou em **Usuários** | +| O painel pede **Novo PIN** logo depois de um PIN definido pela web | O PIN é mais curto que o mínimo da política; a web aceita 4 a 8 dígitos sem olhar a política | Escolha um PIN que siga a política. Até a v2.11.0, o painel recusava esse PIN com **PIN muito curto (mín. 4)** | +| Um PIN antigo não pode mais ser digitado depois de mudar a política | A política tirou as letras dos cartões, ou o teto ficou menor que o PIN | Defina um PIN novo para a conta no item **Usuários** do painel, na página **Usuários** ou no console | | **PIN já em uso!** | Outra conta tem esse PIN | Escolha outro PIN | | Conta aparece com **bloqueado** no painel | Seis PINs errados seguidos dessa conta | Reinicie o aparelho ou use outra conta | | Tela vermelha **ACESSO BLOQUEADO** | 20 PINs errados desde a última entrada certa | Reinicie o aparelho | diff --git a/docs/analysis/PLANO_STABLE.md b/docs/analysis/PLANO_STABLE.md index e0a96b72..6f8878d7 100644 --- a/docs/analysis/PLANO_STABLE.md +++ b/docs/analysis/PLANO_STABLE.md @@ -84,12 +84,12 @@ de recebê-la pelo ar: o aparelho a recusa no stage, na validação e no aplicad | Imagem | `.bin` assinado (B) | Folga (B) | |---|---:|---:| -| `pico_w_release` | 1.033.213 | 7.171 | +| `pico_w_release` | 1.033.365 | 7.019 | | `pico_w_air` | 1.031.485 | 8.899 | | `pico_w_alpha` | 990.621 | 49.763 | -| `pico2_w_release` | 997.265 | 571.503 | -| `pico_w_test` | 1.037.789 | 2.595 | -| `pico_w_asserts` | 1.035.509 | 4.875 | +| `pico2_w_release` | 997.425 | 571.343 | +| `pico_w_test` | 1.037.941 | 2.443 | +| `pico_w_asserts` | 1.035.661 | 4.723 | | `pico_w_test_https` | isenta | — | diff --git a/src/AppManager_Panel.cpp b/src/AppManager_Panel.cpp index 5eca5828..318aec80 100644 --- a/src/AppManager_Panel.cpp +++ b/src/AppManager_Panel.cpp @@ -165,8 +165,11 @@ void AppManager::panelIdentify( ) { * shorter than the new minimum or it uses characters the new alphabet does * not have. The account still identifies (its digest did not change), and * the first thing it does is choose a PIN that complies. The admin's factory - * "1234" arrives here the same way. */ - if (_storageMgr->pinMustChange(slot)) { + * "1234" arrives here the same way. So does a PIN that proved shorter than + * the policy without a mark, as one the web set (PinKb::changeAfterProof): + * the keypad takes any length since 2026-10-04, and this is what still holds + * it to the policy. */ + if (PinKb::changeAfterProof(_storageMgr->pinMustChange(slot), n, _displayMgr->pinMinLen( ))) { _displayMgr->showPinEntry(DisplayManager::PIN_FOR_OWN, -1, true); LOG_CODE(LOG_WARN, "SEC", SEC_UNAUTHORIZED, (int)slot, TRL("PIN does not meet the policy; forcing change.")); diff --git a/src/DisplayManager.h b/src/DisplayManager.h index 1eb6875e..7d7972d7 100644 --- a/src/DisplayManager.h +++ b/src/DisplayManager.h @@ -606,6 +606,9 @@ class DisplayManager { uint8_t pinKeypadMode( ) const; uint8_t pinAlphabet( ) const; uint8_t pinMinLen( ) const; + /** The shortest entry this screen takes: the policy's minimum to choose + * a PIN, PIN_LEN_MIN to prove one (PinKb::entryMinLen). */ + uint8_t pinEntryMinLen( ) const; /** The policy editor (PERM_USER_MGR): length, keypad, alphabet. */ void showPinPolicy( ); #endif /* SIMUT_PANEL_PIN — an image with no touch panel proves nobody */ diff --git a/src/DisplayManager_Users.cpp b/src/DisplayManager_Users.cpp index d4e3f007..00867b22 100644 --- a/src/DisplayManager_Users.cpp +++ b/src/DisplayManager_Users.cpp @@ -30,6 +30,7 @@ #include "UiWidgets.h" #include "SystemDefs_Validate.h" /* PIN_MIN_LEN / PIN_MAX_LEN */ #include "StorageManager.h" /* userHasPin */ +#include "display/CountInText.h" /* the minimum inside the too-short line */ #include "sensors/SensorChannelTable.h" /* Geometry and character set: PinKeypad.h, shared with the CLI readout. */ @@ -163,6 +164,9 @@ uint8_t DisplayManager::pinAlphabet( ) const { uint8_t DisplayManager::pinMinLen( ) const { uint8_t minLen, keypad, alphabet; pinPolicy(minLen, keypad, alphabet); return minLen; } +uint8_t DisplayManager::pinEntryMinLen( ) const { + return PinKb::entryMinLen(pinIsIdentifying( ), pinMinLen( )); +} /* The four cards, for `show display keypad`. The bench drives the panel from * outside and cannot find a digit whose position it was never told; the cards @@ -313,7 +317,7 @@ void DisplayManager::pinCancel( ) { /* OK from the keypad. For identification the PIN goes to Core 0 as is; for a * new PIN it is typed twice, compared here, and only then handed over. */ void DisplayManager::pinSubmit( ) { - if (_pinLen < pinMinLen( )) { + if (_pinLen < pinEntryMinLen( )) { _pinMsg = TR_PIN_TOO_SHORT; _errorSoundPending = true; _repaintSettings = true; @@ -487,16 +491,25 @@ void DisplayManager::drawPinDotsInto(GFXcanvas16* cv, int16_t oy) { cv->setFont(&simutFont9pt); cv->setTextColor(err ? C_TEMP_HOT : C_TEXT_SUB); String m = tr(err ? _pinMsg : TR_LOADING); + if (_pinMsg == TR_PIN_TOO_SHORT) { + /* The line says where its minimum goes ("{n}"); it used to carry a + * 4 that no policy could change. */ + char line[64]; + countInText(m.c_str( ), pinEntryMinLen( ), line, sizeof(line)); + m = line; + } cv->getTextBounds(m, 0, 0, &bx, &by, &bw, &bh); cv->setCursor((320 - bw) / 2, (int16_t)(y + 19)); cv->print(m); return; } - /* The row is as wide as the policy's minimum, or as what has been typed - * past it. Sixteen dots at the old 20-px pitch is 320 px, one wider than - * the safe area allows (measured 2026-09-20), so both pitch and radius - * step down past fourteen. */ - const int floorLen = (int)pinMinLen( ); + /* The row is as wide as the shortest entry this screen takes, or as what + * has been typed past it: the policy's minimum to choose a PIN, the + * absolute floor to prove one, which a PIN set under an older policy may + * be. Sixteen dots at the old 20-px pitch is 320 px, one wider than the + * safe area allows (measured 2026-09-20), so both pitch and radius step + * down past fourteen. */ + const int floorLen = (int)pinEntryMinLen( ); const int n = (_pinLen > floorLen) ? _pinLen : floorLen; const int spacing = dotSpacing(n); const int16_t r = dotRadius(n); diff --git a/src/DisplayManager_i18n.cpp b/src/DisplayManager_i18n.cpp index 8fe628de..177151c7 100644 --- a/src/DisplayManager_i18n.cpp +++ b/src/DisplayManager_i18n.cpp @@ -74,7 +74,7 @@ static const char* const DICTIONARY_EN[TR_KEYS_COUNT] = { "Enter your PIN", "New PIN", "Confirm PIN", - "PIN too short (min 4)", + "PIN too short (min {n})", "PINs don't match!", "PIN already in use!", "PIN saved!", diff --git a/src/PinKeypad.h b/src/PinKeypad.h index 858caa11..5e875774 100644 --- a/src/PinKeypad.h +++ b/src/PinKeypad.h @@ -116,6 +116,28 @@ inline uint8_t maxLenFor(uint8_t keypad) { return (keypad >= KB_MIN && keypad <= KB_MAX) ? LEN_MAX[keypad] : LEN_MAX[KB_SET3]; } +/** The shortest entry the keypad takes. Choosing a PIN follows the policy. + * Proving one takes any length a PIN may still have, from PIN_LEN_MIN up: + * a stricter policy marks every PIN to be changed (markPinsBelowPolicy) so + * that an account whose PIN is now too short identifies with it and is sent + * to the change, and Core 0 resolves any length from PIN_LEN_MIN. The + * keypad refused that entry as too short instead, and the account was out + * of the panel (on the rig, 2026-10-04: 4 digits under a minimum of 5). */ +inline uint8_t entryMinLen(bool identifying, uint8_t policyMin) { + return identifying ? PIN_LEN_MIN : policyMin; +} + +/** After a PIN is proved, must the account choose a new one before it goes + * on? When a stricter policy marked it, and whenever the PIN just proved is + * shorter than the policy's minimum: a tap is a character, so the entry's + * length is the PIN's. The second covers a PIN no tightening marked, as one + * the web set below the policy (the web does not check it), which the + * keypad's refusal used to hold to the policy and entryMinLen( ) now lets + * through. */ +inline bool changeAfterProof(bool marked, uint8_t entryLen, uint8_t policyMin) { + return marked || entryLen < policyMin; +} + /* ── The lockout ladder ────────────────────────────────────────────────── * Six failures take the ACCOUNT out until reboot; PANEL_FAIL_CEILING failures * across all accounts take the PANEL out. Both are needed: only-per-panel is diff --git a/src/display/CountInText.h b/src/display/CountInText.h new file mode 100644 index 00000000..e3737774 --- /dev/null +++ b/src/display/CountInText.h @@ -0,0 +1,34 @@ +/** + * @file display/CountInText.h + * @brief A translated line with a number in it. + * + * The panel's lines come from a language pack, which an administrator + * uploads. A line that needs a number carries "{n}" where the number goes, + * and this puts it there. Not snprintf on the line: a pack line is never a + * format string, so a "%s" in it prints as "%s" instead of reading whatever + * the stack holds. A line without the marker comes back as it is, which is + * what a pack older than the marker shows. Header-only, so a host test + * reaches it (test_validators). + * + * @project SIMUT — Integrated Universal Monitoring and Telemetry System + * @license MIT License + */ + +#pragma once + +#include