This is an automated email from the ASF dual-hosted git repository. xiaoxiang781216 pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit e9c9cba51dec7d3c3a4382b1b00e093f2b886ac8 Author: Abhishek Mishra <[email protected]> AuthorDate: Wed Jul 8 08:32:02 2026 +0000 boards: add CI ROMFS passwd credentials and refresh docs Support NUTTX_ROMFS_PASSWD_PASSWORD via update_romfs_password.sh for configs that enable ROMFS passwd without a defconfig password (sim/login CI). Enable RANDOMIZE_KEYS in sim/login defconfig. Update mkpasswd.c header, platform docs, and the mkpasswd_autogen guide. Signed-off-by: Abhishek Mishra <[email protected]> --- .github/workflows/build.yml | 6 + Documentation/components/tools/index.rst | 150 +++++++++++++++------ .../renesas/rx65n/boards/rx65n-grrose/index.rst | 23 ++-- .../platforms/sim/sim/boards/sim/index.rst | 49 +++---- boards/Kconfig | 10 +- boards/sim/sim/sim/configs/login/defconfig | 1 + cmake/nuttx_add_romfs.cmake | 28 +++- tools/configure.sh | 3 + tools/gen_passwd_keys.sh | 7 +- tools/mkpasswd.c | 69 ++++++---- tools/passwd_keys.mk | 5 +- tools/update_romfs_password.sh | 75 +++++++++++ 12 files changed, 307 insertions(+), 119 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d7405cfb341..77c3abe6037 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -145,6 +145,10 @@ jobs: runs-on: ubuntu-latest env: DOCKER_BUILDKIT: 1 + # Documented sim/login CI test credential (not a production secret). + # Used when CONFIG_BOARD_ETC_ROMFS_PASSWD_ENABLE=y and defconfig omits + # the password. See tools/update_romfs_password.sh. + NUTTX_ROMFS_PASSWD_PASSWORD: NuttXSimLogin1 strategy: max-parallel: 12 @@ -311,6 +315,8 @@ jobs: runs-on: macos-15-intel needs: macOS-Arch if: ${{ needs.macOS-Arch.outputs.skip_all_builds != '1' }} + env: + NUTTX_ROMFS_PASSWD_PASSWORD: NuttXSimLogin1 strategy: max-parallel: 2 matrix: diff --git a/Documentation/components/tools/index.rst b/Documentation/components/tools/index.rst index 23a14c174c7..3e068648164 100644 --- a/Documentation/components/tools/index.rst +++ b/Documentation/components/tools/index.rst @@ -17,64 +17,130 @@ and host C programs that are important parts of the NuttX build system: mkpasswd — Build-time ``/etc/passwd`` Generation ------------------------------------------------- -``tools/mkpasswd`` is a host tool (``tools/mkpasswd.c``) that generates a -single ``/etc/passwd`` entry at build time. It runs automatically when -``CONFIG_BOARD_ETC_ROMFS_PASSWD_ENABLE=y``. +``tools/mkpasswd`` (``tools/mkpasswd.c``) is a host program that writes a +single ``/etc/passwd`` entry with a TEA-encrypted password hash. The +plaintext password is **not** stored in the firmware image. -The plaintext password is hashed with TEA and is not stored in the firmware. -The build fails if the password is empty or uses known insecure defaults. +When ``CONFIG_BOARD_ETC_ROMFS_PASSWD_ENABLE=y``, the build invokes +``mkpasswd`` automatically from ``boards/Board.mk`` (Make) or +``cmake/nuttx_add_romfs.cmake`` (CMake). You normally configure the +password and keys in menuconfig; you do not run ``mkpasswd`` by hand. -Setup -~~~~~ +Prerequisites +~~~~~~~~~~~~~ -1. Run ``make menuconfig`` and configure: +Enable all of the following (via ``make menuconfig``): - * **Board Selection** → Auto-generate /etc/passwd at build time - * Set the admin password (required, minimum 8 characters) - * Enable random TEA key generation, or set keys manually (see below) - * **Application Configuration** → NSH Library → Console Login - * Set verification method to **Encrypted password file** - * **Application Configuration** → File System Utilities → Password file support - * Enable password file support +* **Board Selection** → **Auto-generate /etc/passwd at build time** + (``CONFIG_BOARD_ETC_ROMFS_PASSWD_ENABLE``) +* **Application Configuration** → **NSH Library** → **Console Login** + (``CONFIG_NSH_CONSOLE_LOGIN``) with verification method **Encrypted + password file** (``CONFIG_NSH_LOGIN_PASSWD``) +* **Application Configuration** → **File System Utilities** → **Password file + support** (``CONFIG_FSUTILS_PASSWD``) -2. Run ``make``. +Setup workflow +~~~~~~~~~~~~~~ + +1. ``tools/configure.sh <board>:<config>`` +2. ``make menuconfig``: + + * **Board Selection** → Auto-generate /etc/passwd + + * **Admin password** — required, at least 8 characters. There is no + Kconfig default (the legacy ``Administrator`` password is rejected). + * **Generate random TEA encryption keys automatically** — recommended; + or disable this and set keys manually (see below). + + * Confirm NSH uses **Encrypted password file** verification (above). + +3. ``make`` — on the first build, ``tools/passwd_keys.mk`` validates the + password and keys, may generate TEA keys, then ``mkpasswd`` runs before + ``config.h`` is created so the hash and firmware always agree. + +Build-time credentials (CI / automation) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +These values are **not** written to defconfig by ``make savedefconfig``: + +* ``CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD`` +* ``CONFIG_FSUTILS_PASSWD_KEY1`` … ``CONFIG_FSUTILS_PASSWD_KEY4`` + +For scripted or CI builds, export the admin password before ``configure.sh`` +or ``make``: + +.. code:: bash + + export NUTTX_ROMFS_PASSWD_PASSWORD="your-password-here" + +``tools/update_romfs_password.sh`` copies this into ``.config`` when ROMFS +passwd generation is enabled and the password field is still empty. NuttX +CI sets ``NuttXSimLogin1`` for the ``sim/login`` configuration (a documented +sim-only test credential, not a product secret). TEA encryption keys ~~~~~~~~~~~~~~~~~~~ -Keys must match between the build (``mkpasswd``) and the firmware -(``CONFIG_FSUTILS_PASSWD_KEY1..4``). Choose one option: +``mkpasswd`` and the firmware must use the **same** four 32-bit key words +(``CONFIG_FSUTILS_PASSWD_KEY1`` … ``KEY4``). Choose one approach: + +**Random generation** (``CONFIG_BOARD_ETC_ROMFS_PASSWD_RANDOMIZE_KEYS=y``): -* **Random generation** (``CONFIG_BOARD_ETC_ROMFS_PASSWD_RANDOMIZE_KEYS=y``): - On the first build, four keys are generated from ``/dev/urandom`` and - written to ``.config``. Key values are not printed in the build log. - Search ``.config`` for ``CONFIG_FSUTILS_PASSWD_KEY`` to view them. + On the first ``make`` when keys are missing or still placeholders, + ``tools/gen_passwd_keys.sh`` writes random values to ``.config``. A + build warning explains where to view or change them in menuconfig. Key + values are never printed in the build log. -* **Manual**: Set ``CONFIG_FSUTILS_PASSWD_KEY1..4`` under Password file - support to unique non-zero values. +**Manual keys** (``CONFIG_BOARD_ETC_ROMFS_PASSWD_RANDOMIZE_KEYS`` disabled): -Kconfig options -~~~~~~~~~~~~~~~ + Set ``CONFIG_FSUTILS_PASSWD_KEY1`` … ``KEY4`` under **Application + Configuration** → **File System Utilities** → **Password file support**. + Each must be a unique non-zero value. The legacy published defaults + ``0x12345678`` / ``0x9abcdef0`` are rejected. + +If random generation is enabled but keys are already present in ``.config``, +they are **not** regenerated (subsequent builds stay consistent). + +How the build enforces security +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ++---------------------------+-----------------------------------------------+ +| Check | Where | ++===========================+===============================================+ +| Password set, min 8 chars | ``tools/passwd_keys.mk`` (before ``config.h``)| +| Not ``Administrator`` | ``tools/mkpasswd.c`` (last line of defence) | +| TEA keys configured | ``tools/check_passwd_keys.sh`` | +| Not legacy default keys | ``check_passwd_keys.sh`` + ``mkpasswd.c`` | ++---------------------------+-----------------------------------------------+ + +Standalone ``mkpasswd`` (advanced) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +For debugging only, you may run the host binary directly. You must pass all +four ``--key`` options with non-default values and a password of at least 8 +characters: + +.. code:: bash + + ./tools/mkpasswd --user root --password 'my-secret' \ + --key1 0x11111111 --key2 0x22222222 \ + --key3 0x33333333 --key4 0x44444444 + +Kconfig summary +~~~~~~~~~~~~~~~~~ + +Example ``.config`` fragment (password and keys normally **not** in defconfig): .. code:: kconfig CONFIG_BOARD_ETC_ROMFS_PASSWD_ENABLE=y - CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD="<secret>" CONFIG_BOARD_ETC_ROMFS_PASSWD_RANDOMIZE_KEYS=y + CONFIG_BOARD_ETC_ROMFS_PASSWD_USER="root" + CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD="<set in menuconfig or env>" CONFIG_NSH_CONSOLE_LOGIN=y CONFIG_NSH_LOGIN_PASSWD=y CONFIG_FSUTILS_PASSWD=y -How it works -~~~~~~~~~~~~ - -1. ``tools/passwd_keys.mk`` checks the password and TEA keys before - ``config.h`` is generated. -2. If random generation is enabled and keys are not set, ``gen_passwd_keys.sh`` - writes new keys to ``.config``. -3. ``mkpasswd`` hashes the password with the configured TEA keys. -4. The entry is embedded in the ROMFS image as ``/etc/passwd``. - ``/etc/passwd`` file format ~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -85,9 +151,7 @@ How it works Notes on ``savedefconfig`` ~~~~~~~~~~~~~~~~~~~~~~~~~~ -``make savedefconfig`` does not save these options: - -* ``CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD`` -* ``CONFIG_FSUTILS_PASSWD_KEY1`` through ``CONFIG_FSUTILS_PASSWD_KEY4`` - -Do not copy them into a defconfig or commit them to version control. \ No newline at end of file +``make savedefconfig`` omits the password and ``KEY1``–``KEY4`` from the +generated defconfig on purpose. ``CONFIG_BOARD_ETC_ROMFS_PASSWD_RANDOMIZE_KEYS`` +may remain in defconfig (policy, not a secret). Do not commit passwords or +key values to version control. diff --git a/Documentation/platforms/renesas/rx65n/boards/rx65n-grrose/index.rst b/Documentation/platforms/renesas/rx65n/boards/rx65n-grrose/index.rst index 537542c9394..883b9d2a405 100644 --- a/Documentation/platforms/renesas/rx65n/boards/rx65n-grrose/index.rst +++ b/Documentation/platforms/renesas/rx65n/boards/rx65n-grrose/index.rst @@ -494,31 +494,28 @@ mounted at /etc and will look like this at run-time: start-up script; ``/etc/passwd`` is the password file. The ``/etc/passwd`` file is auto-generated at build time when -``CONFIG_BOARD_ETC_ROMFS_PASSWD_ENABLE`` is set. Enable the option and set -credentials via ``make menuconfig``: +``CONFIG_BOARD_ETC_ROMFS_PASSWD_ENABLE`` is set. See :ref:`mkpasswd_autogen` +for the full setup (admin password, TEA keys, NSH encrypted-password login). * ``CONFIG_BOARD_ETC_ROMFS_PASSWD_ENABLE=y`` * ``CONFIG_BOARD_ETC_ROMFS_PASSWD_USER`` (default: ``root``) -* ``CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD`` (required, build fails if empty) +* Admin password and TEA keys — set in menuconfig (not saved in defconfig) -The password is hashed with TEA at build time by the host tool -``tools/mkpasswd``; the plaintext is **not** stored in the firmware. - -For the full description of the mechanism, TEA key configuration, file format, -and verification steps, see :ref:`mkpasswd_autogen`. +The password is hashed with TEA by ``tools/mkpasswd``; the plaintext is **not** +stored in the firmware. The format of the password file is: .. code:: text - user:x:uid:gid:home + user:encrypted_hash:uid:gid:home Where: user: User name - x: Encrypted password - uid: User ID (0 for now) - gid: Group ID (0 for now) - home: Login directory (/ for now) + encrypted_hash: TEA-encrypted password (base64) + uid: User ID + gid: Group ID + home: Login directory ``/etc/group`` is a group file. It is not currently used. diff --git a/Documentation/platforms/sim/sim/boards/sim/index.rst b/Documentation/platforms/sim/sim/boards/sim/index.rst index d89ce5f5f84..635aabcac0a 100644 --- a/Documentation/platforms/sim/sim/boards/sim/index.rst +++ b/Documentation/platforms/sim/sim/boards/sim/index.rst @@ -1927,10 +1927,14 @@ This is a configuration with login password protection for NSH. .. note:: - This config has password protection enabled. The default login info is: + This config has password protection enabled. After configuring from + defconfig, set the admin password in menuconfig (Board Selection → + Auto-generate /etc/passwd) or export ``NUTTX_ROMFS_PASSWD_PASSWORD`` + before building. NuttX CI uses the documented test password + ``NuttXSimLogin1`` for this configuration. - * USERNAME: root - * PASSWORD: Administrator + * USERNAME: root (default) + * PASSWORD: set at build time (not stored in defconfig) The encrypted password is retained in ``/etc/passwd``. You can disable the password protection by @@ -2133,41 +2137,30 @@ mounted at ``/etc`` and will look like this at run-time: start-up script; ``/etc/passwd`` is the password file. The ``/etc/passwd`` file is auto-generated at build time when -``CONFIG_BOARD_ETC_ROMFS_PASSWD_ENABLE`` is set. Enable the option and set -credentials via ``make menuconfig``: +``CONFIG_BOARD_ETC_ROMFS_PASSWD_ENABLE`` is set. Configure credentials in +``make menuconfig`` (see :ref:`mkpasswd_autogen`): * ``CONFIG_BOARD_ETC_ROMFS_PASSWD_ENABLE=y`` -* ``CONFIG_NSH_CONSOLE_LOGIN=y`` (required, otherwise login is not enforced) +* ``CONFIG_NSH_CONSOLE_LOGIN=y`` with **Encrypted password file** verification * ``CONFIG_BOARD_ETC_ROMFS_PASSWD_USER`` (default: ``root``) -* ``CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD`` (required, build fails if empty or shorter than 8 characters) +* Admin password — required in menuconfig or via ``NUTTX_ROMFS_PASSWD_PASSWORD`` + (minimum 8 characters; not saved in defconfig) +* TEA keys — enable **Generate random TEA encryption keys automatically**, or + set ``CONFIG_FSUTILS_PASSWD_KEY1`` … ``KEY4`` manually -The password is hashed with TEA at build time by the host tool -``tools/mkpasswd``; the plaintext is **not** stored in the firmware. +The password is hashed with TEA by ``tools/mkpasswd``; the plaintext is **not** +stored in the firmware. -For the full description of the build-time password generation mechanism, -TEA key configuration, file format, and verification steps, see -:ref:`mkpasswd_autogen`. - -The format of the password file is: - -.. code:: text - - user:x:uid:gid:home - -Where: - -* user: User name -* x: Encrypted password -* uid: User ID (0 for now) -* gid: Group ID (0 for now) -* home: Login directory (/ for now) - -For configuration, verification steps, and TEA key details, see +For the full build flow, CI credentials, and verification steps, see :ref:`mkpasswd_autogen`. Login test inside the simulator ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Use the admin password you set at build time (menuconfig or +``NUTTX_ROMFS_PASSWD_PASSWORD``). For ``sim/login``, CI uses the documented +test password ``NuttXSimLogin1``; see :ref:`mkpasswd_autogen`. + .. code:: console $ ./nuttx diff --git a/boards/Kconfig b/boards/Kconfig index e26daf68c4f..b4f7eaeb681 100644 --- a/boards/Kconfig +++ b/boards/Kconfig @@ -5622,7 +5622,9 @@ config BOARD_ETC_ROMFS_PASSWD_PASSWORD provided. The build fails if this is empty or shorter than 8 characters. - Not saved in defconfig. + Not saved in defconfig. For CI or scripted builds, set the + environment variable NUTTX_ROMFS_PASSWD_PASSWORD instead (see + tools/update_romfs_password.sh). comment "--- Step 2: choose how to supply the TEA encryption keys ---" @@ -5638,10 +5640,12 @@ config BOARD_ETC_ROMFS_PASSWD_RANDOMIZE_KEYS make Key values are not printed in the build log. Search .config for - CONFIG_FSUTILS_PASSWD_KEY to view them. + CONFIG_FSUTILS_PASSWD_KEY to view them. A build warning is printed + when keys are first generated. Do not copy keys or the password into a defconfig or commit - them to version control. + them to version control. CONFIG_BOARD_ETC_ROMFS_PASSWD_RANDOMIZE_KEYS + may remain in defconfig; the password and KEY1..4 may not. If disabled, set CONFIG_FSUTILS_PASSWD_KEY1..4 manually under Application Configuration -> File System Utilities -> diff --git a/boards/sim/sim/sim/configs/login/defconfig b/boards/sim/sim/sim/configs/login/defconfig index fc1213045e4..3021775d333 100644 --- a/boards/sim/sim/sim/configs/login/defconfig +++ b/boards/sim/sim/sim/configs/login/defconfig @@ -14,6 +14,7 @@ CONFIG_ARCH_SIM=y CONFIG_BOARDCTL_APP_SYMTAB=y CONFIG_BOARDCTL_POWEROFF=y CONFIG_BOARD_ETC_ROMFS_PASSWD_ENABLE=y +CONFIG_BOARD_ETC_ROMFS_PASSWD_RANDOMIZE_KEYS=y CONFIG_BOARD_LOOPSPERMSEC=0 CONFIG_BOOT_RUNFROMEXTSRAM=y CONFIG_BUILTIN=y diff --git a/cmake/nuttx_add_romfs.cmake b/cmake/nuttx_add_romfs.cmake index 2b5c11d4184..868ea4d118c 100644 --- a/cmake/nuttx_add_romfs.cmake +++ b/cmake/nuttx_add_romfs.cmake @@ -284,6 +284,25 @@ function(process_all_directory_romfs) # Auto-generate /etc/passwd at build time if configured if(CONFIG_BOARD_ETC_ROMFS_PASSWD_ENABLE) + execute_process(COMMAND "${NUTTX_DIR}/tools/update_romfs_password.sh" + "${NUTTX_DIR}/.config" RESULT_VARIABLE _cred_rc) + if(NOT _cred_rc EQUAL 0) + message(FATAL_ERROR "update_romfs_password.sh failed (rc=${_cred_rc})") + endif() + + file( + STRINGS "${NUTTX_DIR}/.config" _passwd_line + REGEX "^CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD=" + LIMIT_COUNT 1) + if(_passwd_line MATCHES "^CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD=(.*)$") + set(CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD "${CMAKE_MATCH_1}") + string(STRIP "${CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD}" + CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD) + string(REGEX + REPLACE "^\"(.*)\"$" "\\1" CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD + "${CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD}") + endif() + if("${CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD}" STREQUAL "") message( FATAL_ERROR @@ -360,7 +379,7 @@ function(process_all_directory_romfs) execute_process( COMMAND "${NUTTX_DIR}/tools/gen_passwd_keys.sh" "${NUTTX_DIR}/.config" RESULT_VARIABLE _gen_rc - OUTPUT_QUIET) + OUTPUT_QUIET ERROR_QUIET) if(NOT _gen_rc EQUAL 0) message( FATAL_ERROR @@ -368,9 +387,10 @@ function(process_all_directory_romfs) ) endif() message( - STATUS - "[passwd] TEA keys written to .config (search for CONFIG_FSUTILS_PASSWD_KEY to view)" - ) + WARNING "[passwd] TEA keys auto-generated in .config. " + "View: search .config for CONFIG_FSUTILS_PASSWD_KEY. " + "Change: menuconfig -> Application Configuration -> " + "File System Utilities -> Password file support.") # Re-read .config so the new key values are live for this configure run # (mirrors Board.mk's second -include). diff --git a/tools/configure.sh b/tools/configure.sh index e01e0cb11c9..47a53e4176e 100755 --- a/tools/configure.sh +++ b/tools/configure.sh @@ -356,6 +356,9 @@ echo "CONFIG_BASE_DEFCONFIG=\"$posboardconfig\"" >> "${dest_config}" ${TOPDIR}/tools/sethost.sh $host $* +# Supply ROMFS admin password from NUTTX_ROMFS_PASSWD_PASSWORD when absent +"${TOPDIR}/tools/update_romfs_password.sh" "${dest_config}" + # Save the original configuration file without CONFIG_BASE_DEFCONFIG # for later comparison diff --git a/tools/gen_passwd_keys.sh b/tools/gen_passwd_keys.sh index e744a5a7824..c2ad13805b6 100755 --- a/tools/gen_passwd_keys.sh +++ b/tools/gen_passwd_keys.sh @@ -85,5 +85,8 @@ else } fi -printf 'TEA keys generated and written to %s.\nSearch %s for CONFIG_FSUTILS_PASSWD_KEY to view if needed.\n' \ - "${CONFIG}" "${CONFIG}" +# User-visible notice (stderr): key values are never printed. +printf 'WARNING: [passwd] TEA keys auto-generated in %s\n' "${CONFIG}" >&2 +printf 'WARNING: [passwd] View: search .config for CONFIG_FSUTILS_PASSWD_KEY\n' >&2 +printf 'WARNING: [passwd] Change: make menuconfig -> Application Configuration\n' >&2 +printf 'WARNING: [passwd] -> File System Utilities -> Password file support\n' >&2 diff --git a/tools/mkpasswd.c b/tools/mkpasswd.c index f7952e24e08..9eb2fe55525 100644 --- a/tools/mkpasswd.c +++ b/tools/mkpasswd.c @@ -22,31 +22,45 @@ /**************************************************************************** * Description: - * Host build tool that generates a NuttX /etc/passwd entry with a - * TEA-encrypted password hash. This is a pure C replacement for the - * former tools/mkpasswd.py, removing the Python dependency from the build. + * Host tool that writes one NuttX /etc/passwd line with a TEA-encrypted + * password hash. The plaintext password is never stored in the output. * - * The encryption algorithm and base64 encoding are identical to those - * used at runtime by: - * libs/libc/misc/lib_tea_encrypt.c - * apps/fsutils/passwd/passwd_encrypt.c + * Build integration: + * When ``CONFIG_BOARD_ETC_ROMFS_PASSWD_ENABLE=y``, ``boards/Board.mk`` + * invokes this program during the ROMFS etc/ image build. The password + * and TEA keys are taken from ``.config`` (see ``tools/passwd_keys.mk``, + * ``tools/update_romfs_password.sh``, and + * Documentation/components/tools/index.rst). * - * Usage: - * mkpasswd --user <name> --password <pass> [options] [-o <output>] + * Runtime compatibility: + * The encryption algorithm and base64 encoding match: + * libs/libc/misc/lib_tea_encrypt.c + * apps/fsutils/passwd/passwd_encrypt.c + * + * Security (enforced before writing output): + * - Password must be non-empty and at least 8 characters. + * - Password ``Administrator`` is rejected (legacy insecure default). + * - The published default TEA key set (0x12345678 / 0x9abcdef0) + * is rejected. Use Kconfig keys or explicit --key options. + * + * Standalone usage (advanced / debugging only): + * mkpasswd --user <name> --password <pass> \\ + * --key1 <hex> --key2 <hex> --key3 <hex> --key4 <hex> \\ + * [-o <output>] * * Options: * --user <str> Username (required) - * --password <str> Plaintext password (required, not stored in output) + * --password <str> Plaintext password (required, min 8 characters) * --uid <int> User ID (default: 0) * --gid <int> Group ID (default: 0) * --home <str> Home directory (default: /) - * --key1 <hex> TEA key word 1 (default: 0x12345678) - * --key2 <hex> TEA key word 2 (default: 0x9abcdef0) - * --key3 <hex> TEA key word 3 (default: 0x12345678) - * --key4 <hex> TEA key word 4 (default: 0x9abcdef0) + * --key1 <hex> TEA key word 1 (required for standalone use) + * --key2 <hex> TEA key word 2 (required for standalone use) + * --key3 <hex> TEA key word 3 (required for standalone use) + * --key4 <hex> TEA key word 4 (required for standalone use) * -o <path> Output file (default: stdout) * - * Output format (matches NuttX passwd file format): + * Output format: * username:encrypted_hash:uid:gid:home * ****************************************************************************/ @@ -89,9 +103,9 @@ #define MAX_PASSWORD (3 * MAX_ENCRYPTED / 4) /* Max plaintext length */ #define MIN_PASSWORD 8 /* Minimum plaintext length for security */ -/* Default TEA key values - must match CONFIG_FSUTILS_PASSWD_KEY1-4 defaults - * in apps/fsutils/passwd/Kconfig so that the generated hash verifies - * correctly at runtime when the user has not changed the key config. +/* Known-insecure TEA key values from legacy NuttX releases. Used only to + * detect and reject the published default set in main(); normal builds pass + * keys from CONFIG_FSUTILS_PASSWD_KEY1..4 via boards/Board.mk. */ #define DEFAULT_KEY1 0x12345678u @@ -391,23 +405,28 @@ static int mkdir_p(const char *path) static void show_usage(const char *progname) { fprintf(stderr, - "Usage: %s --user <name> --password <pass> [options] [-o <file>]\n" + "Usage: %s --user <name> --password <pass>\n" + " --key1 <hex> --key2 <hex> --key3 <hex> --key4 <hex>\n" + " [options] [-o <file>]\n" "\n" "Options:\n" " --user <str> Username (required)\n" - " --password <str> Plaintext password (required)\n" + " --password <str> Plaintext password (required, min %d chars)\n" " --uid <int> User ID (default: 0)\n" " --gid <int> Group ID (default: 0)\n" " --home <str> Home directory (default: /)\n" - " --key1 <hex> TEA key word 1 (default: 0x%08x)\n" - " --key2 <hex> TEA key word 2 (default: 0x%08x)\n" - " --key3 <hex> TEA key word 3 (default: 0x%08x)\n" - " --key4 <hex> TEA key word 4 (default: 0x%08x)\n" + " --key1 <hex> TEA key word 1\n" + " --key2 <hex> TEA key word 2 (all four required;\n" + " --key3 <hex> TEA key word 3 legacy defaults rejected)\n" + " --key4 <hex> TEA key word 4\n" " -o <path> Output file (default: stdout)\n" "\n" + "Rejected: empty password, \"Administrator\", default TEA keys.\n" + "See Documentation/components/tools/index.rst for normal builds.\n" + "\n" "Output format: username:encrypted_hash:uid:gid:home\n", progname, - DEFAULT_KEY1, DEFAULT_KEY2, DEFAULT_KEY3, DEFAULT_KEY4); + MIN_PASSWORD); } /**************************************************************************** diff --git a/tools/passwd_keys.mk b/tools/passwd_keys.mk index 8817f0ddb56..e91e945fa38 100644 --- a/tools/passwd_keys.mk +++ b/tools/passwd_keys.mk @@ -31,6 +31,10 @@ endif ifeq ($(CONFIG_BOARD_ETC_ROMFS_PASSWD_ENABLE),y) ifeq ($(_PASSWD_ENFORCE),y) +# Apply NUTTX_ROMFS_PASSWD_PASSWORD when defconfig omitted the secret. +$(shell $(TOPDIR)/tools/update_romfs_password.sh $(TOPDIR)/.config >/dev/null 2>&1) +include $(TOPDIR)/.config + # --- password check --- ifeq ($(strip $(patsubst "%",%,$(CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD))),) $(info ) @@ -55,7 +59,6 @@ _PASSWD_KEYS_NEED_SETUP := $(shell \ ifneq ($(_PASSWD_KEYS_NEED_SETUP),no) ifeq ($(CONFIG_BOARD_ETC_ROMFS_PASSWD_RANDOMIZE_KEYS),y) $(shell $(TOPDIR)/tools/gen_passwd_keys.sh $(TOPDIR)/.config >/dev/null) -$(info [passwd] TEA keys written to .config (search for CONFIG_FSUTILS_PASSWD_KEY to view)) include $(TOPDIR)/.config else $(info ) diff --git a/tools/update_romfs_password.sh b/tools/update_romfs_password.sh new file mode 100755 index 00000000000..8b246094263 --- /dev/null +++ b/tools/update_romfs_password.sh @@ -0,0 +1,75 @@ +#!/usr/bin/env sh +# tools/update_romfs_password.sh +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Usage: +# update_romfs_password.sh <path-to-.config> +# +# When CONFIG_BOARD_ETC_ROMFS_PASSWD_ENABLE=y and the admin password is not +# set in .config, copy NUTTX_ROMFS_PASSWD_PASSWORD into .config. This is the +# supported way to supply build-time credentials that must not live in defconfig +# (CI, automation, local scripts). No-op when the password is already set or +# ROMFS passwd generation is disabled. + +set -e + +CONFIG="${1}" +PASSWD_ENV="${NUTTX_ROMFS_PASSWD_PASSWORD:-}" + +if [ -z "${CONFIG}" ]; then + printf 'Usage: update_romfs_password.sh <path-to-.config>\n' >&2 + exit 1 +fi + +if [ ! -f "${CONFIG}" ]; then + exit 0 +fi + +if ! grep -q '^CONFIG_BOARD_ETC_ROMFS_PASSWD_ENABLE=y' "${CONFIG}"; then + exit 0 +fi + +# True when CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD is unset or empty in .config +get_password() { + grep -E '^CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD=' "${CONFIG}" 2>/dev/null \ + | tail -n 1 \ + | sed 's/^[^=]*=//' \ + | tr -d '"' +} + +cur=$(get_password) +if [ -n "${cur}" ]; then + exit 0 +fi + +if [ -z "${PASSWD_ENV}" ]; then + exit 0 +fi + +if [ "${#PASSWD_ENV}" -lt 8 ]; then + printf 'update_romfs_password: NUTTX_ROMFS_PASSWD_PASSWORD must be at least 8 characters\n' >&2 + exit 1 +fi + +if command -v kconfig-tweak >/dev/null 2>&1; then + kconfig-tweak --file "${CONFIG}" \ + --set-str CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD "${PASSWD_ENV}" +else + sed -i.bak -e '/^CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD=/d' "${CONFIG}" + rm -f "${CONFIG}.bak" + printf 'CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD="%s"\n' "${PASSWD_ENV}" >> "${CONFIG}" +fi
