This is an automated email from the ASF dual-hosted git repository. cederom pushed a commit to branch releases/13.0 in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 1017d76dd913d4bf58dd58aeacb359f5202163b9 Author: Alin Jerpelea <[email protected]> AuthorDate: Mon Aug 3 15:32:58 2026 +0200 Revert "!boards: enforce secure ROMFS passwd and TEA key setup" This reverts commit f5291a8df19660fc69992c0763e1a4cc87b7037c. Signed-off-by: Alin Jerpelea <[email protected]> --- Documentation/components/tools/index.rst | 126 +++++++++++++++++++------------ Makefile | 1 - boards/Board.mk | 11 ++- boards/Kconfig | 63 +++++----------- cmake/nuttx_add_romfs.cmake | 104 +++++-------------------- tools/check_passwd_keys.sh | 82 -------------------- tools/gen_passwd_keys.sh | 89 ---------------------- tools/mkpasswd.c | 34 ++++----- tools/passwd_keys.mk | 74 ------------------ 9 files changed, 135 insertions(+), 449 deletions(-) diff --git a/Documentation/components/tools/index.rst b/Documentation/components/tools/index.rst index 23a14c174c7..83c868984fb 100644 --- a/Documentation/components/tools/index.rst +++ b/Documentation/components/tools/index.rst @@ -17,77 +17,107 @@ 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`` is a C host tool (compiled from ``tools/mkpasswd.c``) that +generates a single ``/etc/passwd`` entry at build time. It is invoked +automatically by the ROMFS build step when +``CONFIG_BOARD_ETC_ROMFS_PASSWD_ENABLE=y`` is set. -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. - -Setup -~~~~~ - -1. Run ``make menuconfig`` and configure: - - * **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 - -2. Run ``make``. +Why build-time generation? +~~~~~~~~~~~~~~~~~~~~~~~~~~ -TEA encryption keys -~~~~~~~~~~~~~~~~~~~ +Shipping a hard-coded default password in firmware is a well-known security +weakness (CWE-798). By generating the ``/etc/passwd`` entry from a +user-supplied plaintext password at build time, each firmware image carries +unique credentials. The build will fail if the password is left empty, +preventing accidental deployments with no credentials. -Keys must match between the build (``mkpasswd``) and the firmware -(``CONFIG_FSUTILS_PASSWD_KEY1..4``). Choose one option: +For improved baseline security, the configured password must be at least +8 characters long. -* **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. +How it works +~~~~~~~~~~~~ -* **Manual**: Set ``CONFIG_FSUTILS_PASSWD_KEY1..4`` under Password file - support to unique non-zero values. +1. The host tool reads the plaintext password from + ``CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD``. +2. The password is hashed using the Tiny Encryption Algorithm (TEA) — the + same implementation used at runtime in + ``libs/libc/misc/lib_tea_encrypt.c`` — with custom base64 encoding + matching ``apps/fsutils/passwd/passwd_encrypt.c``. +3. The resulting hashed entry is written to + ``etctmp/<mountpoint>/passwd`` and then embedded into the ROMFS image. +4. The **plaintext password is never stored in the firmware image**. Kconfig options ~~~~~~~~~~~~~~~ +Enable the feature and configure credentials via ``make menuconfig``: + .. 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_NSH_CONSOLE_LOGIN=y - CONFIG_NSH_LOGIN_PASSWD=y - CONFIG_FSUTILS_PASSWD=y - -How it works -~~~~~~~~~~~~ + CONFIG_NSH_CONSOLE_LOGIN=y # required to enforce login prompt + CONFIG_BOARD_ETC_ROMFS_PASSWD_USER="root" # default: root + CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD="<secret>" # required, min length 8 + CONFIG_BOARD_ETC_ROMFS_PASSWD_UID=0 + CONFIG_BOARD_ETC_ROMFS_PASSWD_GID=0 + CONFIG_BOARD_ETC_ROMFS_PASSWD_HOME="/" -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``. +The TEA encryption keys can be changed from their defaults via +``CONFIG_FSUTILS_PASSWD_KEY1..4``. ``/etc/passwd`` file format ~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. code:: text - user:encrypted_hash:uid:gid:home + user:x:uid:gid:home + +Where: + +* ``user`` — user name +* ``x`` — TEA-hashed, base64-encoded password +* ``uid`` — numeric user ID +* ``gid`` — numeric group ID +* ``home`` — login directory + +Verifying the generated entry +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +After enabling ``CONFIG_BOARD_ETC_ROMFS_PASSWD_ENABLE`` and setting a +password, rebuild and verify: + +1. **Configure and build**: + + .. code:: console + + $ make menuconfig # enable BOARD_ETC_ROMFS_PASSWD_ENABLE and set password + $ make + +2. **Inspect the generated passwd line** (written to the board build tree): + + .. code:: console + + $ cat boards/<arch>/<chip>/<board>/src/etctmp/etc/passwd + root:8Tv+Hbmr3pLVb5HHZgd26D:0:0:/ + +3. **Verify the plaintext is absent from firmware**: + + .. code:: console + + $ grep <your-password> boards/<arch>/<chip>/<board>/src/etctmp.c + # must print nothing Notes on ``savedefconfig`` ~~~~~~~~~~~~~~~~~~~~~~~~~~ -``make savedefconfig`` does not save these options: +To avoid leaking credentials into board defconfigs, ``make savedefconfig`` +does not save the following options in the generated defconfig: * ``CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD`` -* ``CONFIG_FSUTILS_PASSWD_KEY1`` through ``CONFIG_FSUTILS_PASSWD_KEY4`` +* ``CONFIG_FSUTILS_PASSWD_KEY1`` +* ``CONFIG_FSUTILS_PASSWD_KEY2`` +* ``CONFIG_FSUTILS_PASSWD_KEY3`` +* ``CONFIG_FSUTILS_PASSWD_KEY4`` -Do not copy them into a defconfig or commit them to version control. \ No newline at end of file +If you need these values for local development, add them manually to your +local defconfig after running ``make savedefconfig``. \ No newline at end of file diff --git a/Makefile b/Makefile index 567d3c6ae8a..ac65abe1121 100644 --- a/Makefile +++ b/Makefile @@ -31,7 +31,6 @@ ifeq ($(wildcard .config),) @echo " tools/configure.sh -L" else include .config -include tools/passwd_keys.mk # Include the correct Makefile for the selected architecture. diff --git a/boards/Board.mk b/boards/Board.mk index a882433aa82..580a18caf73 100644 --- a/boards/Board.mk +++ b/boards/Board.mk @@ -36,6 +36,9 @@ $(ETCSRC): $(foreach raw,$(RCRAWS), $(if $(wildcard $(BOARD_DIR)$(DELIM)src$(DEL $(shell mkdir -p $(dir $(ETCDIR)$(DELIM)$(raw))) \ $(shell cp -rfp $(if $(wildcard $(BOARD_DIR)$(DELIM)src$(DELIM)$(raw)), $(BOARD_DIR)$(DELIM)src$(DELIM)$(raw), $(if $(wildcard $(BOARD_COMMON_DIR)$(DELIM)$(raw)), $(BOARD_COMMON_DIR)$(DELIM)$(raw), $(BOARD_DIR)$(DELIM)src$(DELIM)$(raw))) $(ETCDIR)$(DELIM)$(raw))) ifeq ($(CONFIG_BOARD_ETC_ROMFS_PASSWD_ENABLE),y) +ifeq ($(strip $(patsubst "%",%,$(CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD))),) + $(error CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD must be set when BOARD_ETC_ROMFS_PASSWD_ENABLE is enabled. Run 'make menuconfig' and select a password at: Board Selection ---> Auto-generate /etc/passwd at build time ---> Admin password) +endif $(Q) mkdir -p $(ETCDIR)$(DELIM)$(CONFIG_ETC_ROMFSMOUNTPT) $(Q) $(TOPDIR)$(DELIM)tools$(DELIM)mkpasswd$(HOSTEXEEXT) \ --user $(CONFIG_BOARD_ETC_ROMFS_PASSWD_USER) \ @@ -43,10 +46,10 @@ ifeq ($(CONFIG_BOARD_ETC_ROMFS_PASSWD_ENABLE),y) --uid $(CONFIG_BOARD_ETC_ROMFS_PASSWD_UID) \ --gid $(CONFIG_BOARD_ETC_ROMFS_PASSWD_GID) \ --home $(CONFIG_BOARD_ETC_ROMFS_PASSWD_HOME) \ - --key1 $(CONFIG_FSUTILS_PASSWD_KEY1) \ - --key2 $(CONFIG_FSUTILS_PASSWD_KEY2) \ - --key3 $(CONFIG_FSUTILS_PASSWD_KEY3) \ - --key4 $(CONFIG_FSUTILS_PASSWD_KEY4) \ + $(if $(CONFIG_FSUTILS_PASSWD_KEY1),--key1 $(CONFIG_FSUTILS_PASSWD_KEY1)) \ + $(if $(CONFIG_FSUTILS_PASSWD_KEY2),--key2 $(CONFIG_FSUTILS_PASSWD_KEY2)) \ + $(if $(CONFIG_FSUTILS_PASSWD_KEY3),--key3 $(CONFIG_FSUTILS_PASSWD_KEY3)) \ + $(if $(CONFIG_FSUTILS_PASSWD_KEY4),--key4 $(CONFIG_FSUTILS_PASSWD_KEY4)) \ -o $(ETCDIR)$(DELIM)$(CONFIG_ETC_ROMFSMOUNTPT)$(DELIM)passwd endif $(Q) genromfs -f romfs.img -d $(ETCDIR)$(DELIM)$(CONFIG_ETC_ROMFSMOUNTPT) -V "NSHInitVol" diff --git a/boards/Kconfig b/boards/Kconfig index 957845910ec..85f90948ba7 100644 --- a/boards/Kconfig +++ b/boards/Kconfig @@ -5541,23 +5541,21 @@ config BOARD_ETC_ROMFS_PASSWD_ENABLE default n depends on ETC_ROMFS ---help--- - Generate /etc/passwd at build time. The password is hashed with TEA - by tools/mkpasswd; the plaintext is not stored in the firmware. + Generate the /etc/passwd file at build time from a user-supplied + password. This avoids shipping a hard-coded default password + (CWE-798). When enabled, the build will fail if no password + is configured, forcing each build to set its own credentials. - Before building, set: - 1. Admin password (below) - 2. TEA keys — enable random generation below, or set - CONFIG_FSUTILS_PASSWD_KEY1..4 in Application Configuration -> - File System Utilities -> Password file support + The password is hashed at build time by the host tool + tools/mkpasswd (compiled from tools/mkpasswd.c) using the Tiny + Encryption Algorithm (TEA) — the same algorithm used at runtime + in libs/libc/misc/lib_tea_encrypt.c. The plaintext password is + never stored in the firmware image. - Also enable NSH login with "Encrypted password file" verification. - - Password and keys are not saved in defconfig. Do not commit them. + See Documentation/components/passwd_autogen.rst for details. if BOARD_ETC_ROMFS_PASSWD_ENABLE -comment "--- Step 1: set the admin password below ---" - config BOARD_ETC_ROMFS_PASSWD_USER string "Admin username" default "root" @@ -5565,39 +5563,14 @@ config BOARD_ETC_ROMFS_PASSWD_USER The username for the auto-generated /etc/passwd entry. config BOARD_ETC_ROMFS_PASSWD_PASSWORD - string "Admin password (required, no default)" - ---help--- - The plaintext password for the /etc/passwd entry. No default is - provided. The build fails if this is empty or shorter than 8 - characters. - - Not saved in defconfig. - -comment "--- Step 2: choose how to supply the TEA encryption keys ---" - -config BOARD_ETC_ROMFS_PASSWD_RANDOMIZE_KEYS - bool "Generate random TEA encryption keys automatically" - default n - ---help--- - Generate four random TEA keys from /dev/urandom and write them - to .config on the first build. The same keys are used for the - /etc/passwd hash and the firmware. - - make menuconfig # set password, enable this option - make - - Key values are not printed in the build log. Search .config for - CONFIG_FSUTILS_PASSWD_KEY to view them. - - Do not copy keys or the password into a defconfig or commit - them to version control. - - If disabled, set CONFIG_FSUTILS_PASSWD_KEY1..4 manually under - Application Configuration -> File System Utilities -> - Password file support. - -comment " If not randomizing: set KEY1..4 at App Config -> File System Utilities -> Password file support" - depends on !BOARD_ETC_ROMFS_PASSWD_RANDOMIZE_KEYS + string "Admin password (required)" + default "Administrator" + ---help--- + The plaintext password for the auto-generated /etc/passwd entry. + This value is hashed with TEA at build time; the plaintext is NOT + stored in the firmware image. The build will fail if this is left + empty or shorter than 8 characters. Set this via + 'make menuconfig'. config BOARD_ETC_ROMFS_PASSWD_UID int "Admin user ID" diff --git a/cmake/nuttx_add_romfs.cmake b/cmake/nuttx_add_romfs.cmake index 2b5c11d4184..baca00fb8cf 100644 --- a/cmake/nuttx_add_romfs.cmake +++ b/cmake/nuttx_add_romfs.cmake @@ -287,17 +287,9 @@ function(process_all_directory_romfs) if("${CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD}" STREQUAL "") message( FATAL_ERROR - "\n" - " BUILD ERROR: Admin password not set.\n" - "\n" - " Run make menuconfig and set:\n" - " Board Selection -> Auto-generate /etc/passwd -> Admin password\n" - "\n" - " For TEA keys, either enable random generation in the same menu,\n" - " or set CONFIG_FSUTILS_PASSWD_KEY1..4 under Application Configuration\n" - " -> File System Utilities -> Password file support.\n" - "\n" - " Password and keys are not saved in defconfig.\n") + "CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD must be set when " + "BOARD_ETC_ROMFS_PASSWD_ENABLE is enabled. Run 'make menuconfig' " + "to set a password.") endif() # Determine host executable suffix (.exe on Windows, empty elsewhere) @@ -325,77 +317,22 @@ function(process_all_directory_romfs) add_custom_target(build_host_mkpasswd DEPENDS ${MKPASSWD_BIN}) endif() - set(GENPASSWD_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/etc/passwd) - - # Delegate detection and generation to the shell helpers so the logic is - # testable outside of cmake. check_passwd_keys.sh prints "yes" when keys - # are absent or at insecure defaults; gen_passwd_keys.sh writes fresh - # /dev/urandom values in-place. - # - # RANDOMIZE_KEYS — single-invocation path: 1. gen_passwd_keys.sh writes new - # keys to .config at configure time. 2. We re-read .config below so - # CONFIG_FSUTILS_PASSWD_KEY1..4 carry the new values for the rest of this - # cmake configure run. 3. add_custom_command is registered with the updated - # key values, so both mkpasswd (passwd hash) and the firmware use the same - # keys — login works without a second cmake invocation. - # - # Note: config.h is regenerated at build time from .config (its dependency), - # so the firmware uses the correct keys automatically. - - execute_process( - COMMAND "${NUTTX_DIR}/tools/check_passwd_keys.sh" "${NUTTX_DIR}/.config" - OUTPUT_VARIABLE _passwd_keys_need_setup - OUTPUT_STRIP_TRAILING_WHITESPACE - RESULT_VARIABLE _check_rc) - if(NOT _check_rc EQUAL 0) - message( - FATAL_ERROR - "check_passwd_keys.sh failed — check ${NUTTX_DIR}/tools/check_passwd_keys.sh" - ) + # Pass TEA key overrides when the user has changed them from defaults + set(MKPASSWD_KEY_ARGS "") + if(CONFIG_FSUTILS_PASSWD_KEY1) + list(APPEND MKPASSWD_KEY_ARGS --key1 ${CONFIG_FSUTILS_PASSWD_KEY1}) endif() - - if(_passwd_keys_need_setup STREQUAL "yes") - if(CONFIG_BOARD_ETC_ROMFS_PASSWD_RANDOMIZE_KEYS) - # Generate keys and write to .config (no key values printed here) - execute_process( - COMMAND "${NUTTX_DIR}/tools/gen_passwd_keys.sh" "${NUTTX_DIR}/.config" - RESULT_VARIABLE _gen_rc - OUTPUT_QUIET) - if(NOT _gen_rc EQUAL 0) - message( - FATAL_ERROR - "gen_passwd_keys.sh failed — check ${NUTTX_DIR}/.config permissions" - ) - endif() - message( - STATUS - "[passwd] TEA keys written to .config (search for CONFIG_FSUTILS_PASSWD_KEY to view)" - ) - - # Re-read .config so the new key values are live for this configure run - # (mirrors Board.mk's second -include). - file(STRINGS "${NUTTX_DIR}/.config" _fresh_config - REGEX "^CONFIG_FSUTILS_PASSWD_KEY[1-4]=") - foreach(_line ${_fresh_config}) - if(_line MATCHES "^CONFIG_FSUTILS_PASSWD_KEY([1-4])=(.+)$") - set(CONFIG_FSUTILS_PASSWD_KEY${CMAKE_MATCH_1} "${CMAKE_MATCH_2}") - endif() - endforeach() - else() - message( - FATAL_ERROR - "\n" - " BUILD ERROR: TEA encryption keys not configured.\n" - "\n" - " Run make menuconfig and either:\n" - " - enable Generate random TEA keys automatically, or\n" - " - set CONFIG_FSUTILS_PASSWD_KEY1..4 under Application Configuration\n" - " -> File System Utilities -> Password file support\n") - endif() + if(CONFIG_FSUTILS_PASSWD_KEY2) + list(APPEND MKPASSWD_KEY_ARGS --key2 ${CONFIG_FSUTILS_PASSWD_KEY2}) + endif() + if(CONFIG_FSUTILS_PASSWD_KEY3) + list(APPEND MKPASSWD_KEY_ARGS --key3 ${CONFIG_FSUTILS_PASSWD_KEY3}) + endif() + if(CONFIG_FSUTILS_PASSWD_KEY4) + list(APPEND MKPASSWD_KEY_ARGS --key4 ${CONFIG_FSUTILS_PASSWD_KEY4}) endif() - # At this point KEY1..4 are guaranteed to be correct (either freshly - # generated above, or manually set by the user). + set(GENPASSWD_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/etc/passwd) add_custom_command( OUTPUT ${GENPASSWD_OUTPUT} COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/etc @@ -404,13 +341,10 @@ function(process_all_directory_romfs) --password "${CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD}" --uid ${CONFIG_BOARD_ETC_ROMFS_PASSWD_UID} --gid ${CONFIG_BOARD_ETC_ROMFS_PASSWD_GID} --home - "${CONFIG_BOARD_ETC_ROMFS_PASSWD_HOME}" --key1 - ${CONFIG_FSUTILS_PASSWD_KEY1} --key2 ${CONFIG_FSUTILS_PASSWD_KEY2} - --key3 ${CONFIG_FSUTILS_PASSWD_KEY3} --key4 - ${CONFIG_FSUTILS_PASSWD_KEY4} -o ${GENPASSWD_OUTPUT} + "${CONFIG_BOARD_ETC_ROMFS_PASSWD_HOME}" ${MKPASSWD_KEY_ARGS} -o + ${GENPASSWD_OUTPUT} DEPENDS ${MKPASSWD_BIN} ${NUTTX_DIR}/.config - COMMENT "Generating /etc/passwd from .config TEA keys") - + COMMENT "Generating /etc/passwd from Kconfig values") add_custom_target(generate_passwd DEPENDS ${GENPASSWD_OUTPUT}) add_dependencies(generate_passwd build_host_mkpasswd) list(APPEND RCRAWS ${GENPASSWD_OUTPUT}) diff --git a/tools/check_passwd_keys.sh b/tools/check_passwd_keys.sh deleted file mode 100755 index e6cbe3bf532..00000000000 --- a/tools/check_passwd_keys.sh +++ /dev/null @@ -1,82 +0,0 @@ -#!/usr/bin/env sh -# tools/check_passwd_keys.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: -# check_passwd_keys.sh <path-to-.config> -# -# Prints "yes" to stdout when CONFIG_FSUTILS_PASSWD_KEY1..4 need setup: -# - any key is absent or "is not set" -# - all four equal the known-insecure Kconfig defaults -# Prints "no" when all four are present and non-default. -# Idempotent; no side effects. - -set -e - -CONFIG="${1}" -if [ -z "${CONFIG}" ]; then - printf 'Usage: check_passwd_keys.sh <path-to-.config>\n' >&2 - exit 1 -fi - -if [ ! -f "${CONFIG}" ]; then - printf 'check_passwd_keys: file not found: %s\n' "${CONFIG}" >&2 - exit 1 -fi - -# Known-insecure placeholder/default values — must not be used in a build. -DEFAULT1=0x12345678 -DEFAULT2=0x9abcdef0 -DEFAULT3=0x12345678 -DEFAULT4=0x9abcdef0 - -# Return the assigned value of CONFIG_FSUTILS_PASSWD_KEY<n>, or empty -# string when the line is absent or commented as "is not set". -get_val() { - grep -E "^CONFIG_FSUTILS_PASSWD_KEY${1}=" "${CONFIG}" 2>/dev/null \ - | tail -n 1 \ - | sed 's/^[^=]*=//' -} - -# True when the value is unset or still at the Kconfig placeholder (0). -is_placeholder() { - case "$1" in - ''|0|0x0|0x00000000) return 0 ;; - *) return 1 ;; - esac -} - -K1=$(get_val 1) -K2=$(get_val 2) -K3=$(get_val 3) -K4=$(get_val 4) - -# Any key absent, empty, or placeholder → needs setup -if is_placeholder "${K1}" || is_placeholder "${K2}" || \ - is_placeholder "${K3}" || is_placeholder "${K4}"; then - echo yes - exit 0 -fi - -# All four at the known insecure defaults → needs setup -if [ "${K1}" = "${DEFAULT1}" ] && [ "${K2}" = "${DEFAULT2}" ] && \ - [ "${K3}" = "${DEFAULT3}" ] && [ "${K4}" = "${DEFAULT4}" ]; then - echo yes - exit 0 -fi - -echo no diff --git a/tools/gen_passwd_keys.sh b/tools/gen_passwd_keys.sh deleted file mode 100755 index e744a5a7824..00000000000 --- a/tools/gen_passwd_keys.sh +++ /dev/null @@ -1,89 +0,0 @@ -#!/usr/bin/env sh -# tools/gen_passwd_keys.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: -# gen_passwd_keys.sh <path-to-.config> -# -# Generates four random 32-bit TEA key values from /dev/urandom and -# writes/replaces CONFIG_FSUTILS_PASSWD_KEY1..4 in the target .config file. -# Handles both "line exists (replace)" and "line missing (append)" cases. -# -# Key values are NOT printed to stdout or stderr. Search the .config file -# for CONFIG_FSUTILS_PASSWD_KEY to view them if needed. -# -# Exit 0 on success, non-zero with a message on failure. - -set -e - -CONFIG="${1}" -if [ -z "${CONFIG}" ]; then - printf 'Usage: gen_passwd_keys.sh <path-to-.config>\n' >&2 - exit 1 -fi - -if [ ! -f "${CONFIG}" ]; then - printf 'gen_passwd_keys: file not found: %s\n' "${CONFIG}" >&2 - exit 1 -fi - -# Generate a random 32-bit hex value via /dev/urandom. -# Uses od -tx4 which always produces exactly 8 hex digits. -rand_key() { - dd if=/dev/urandom bs=4 count=1 2>/dev/null \ - | od -An -tx4 \ - | tr -d ' \n' -} - -K1="0x$(rand_key)" -K2="0x$(rand_key)" -K3="0x$(rand_key)" -K4="0x$(rand_key)" - -# Remove any existing definitions (assigned or "is not set") everywhere. -sed -i \ - '/^# CONFIG_FSUTILS_PASSWD_KEY[1-4] is not set/d; - /^CONFIG_FSUTILS_PASSWD_KEY[1-4]=/d' \ - "${CONFIG}" || { - printf 'gen_passwd_keys: ERROR: failed to edit %s (check permissions)\n' \ - "${CONFIG}" >&2 - exit 1 -} - -# Insert keys in the FSUTILS_PASSWD section when it exists so menuconfig -# and mkconfig see a single canonical copy (not orphaned lines at EOF). -if grep -q '^CONFIG_FSUTILS_PASSWD_IOBUFFER_SIZE=' "${CONFIG}"; then - sed -i "/^CONFIG_FSUTILS_PASSWD_IOBUFFER_SIZE=/a\\ -CONFIG_FSUTILS_PASSWD_KEY1=${K1}\\ -CONFIG_FSUTILS_PASSWD_KEY2=${K2}\\ -CONFIG_FSUTILS_PASSWD_KEY3=${K3}\\ -CONFIG_FSUTILS_PASSWD_KEY4=${K4}" "${CONFIG}" || { - printf 'gen_passwd_keys: ERROR: failed to insert keys into %s\n' \ - "${CONFIG}" >&2 - exit 1 - } -else - printf 'CONFIG_FSUTILS_PASSWD_KEY1=%s\nCONFIG_FSUTILS_PASSWD_KEY2=%s\nCONFIG_FSUTILS_PASSWD_KEY3=%s\nCONFIG_FSUTILS_PASSWD_KEY4=%s\n' \ - "${K1}" "${K2}" "${K3}" "${K4}" >> "${CONFIG}" || { - printf 'gen_passwd_keys: ERROR: failed to append keys to %s\n' \ - "${CONFIG}" >&2 - exit 1 - } -fi - -printf 'TEA keys generated and written to %s.\nSearch %s for CONFIG_FSUTILS_PASSWD_KEY to view if needed.\n' \ - "${CONFIG}" "${CONFIG}" diff --git a/tools/mkpasswd.c b/tools/mkpasswd.c index f7952e24e08..cfde64f3b40 100644 --- a/tools/mkpasswd.c +++ b/tools/mkpasswd.c @@ -529,10 +529,7 @@ int main(int argc, char **argv) if (password[0] == '\0') { - fprintf(stderr, - "mkpasswd: ERROR: password must not be empty.\n" - " Set it in menuconfig: Board Selection -> " - "Auto-generate /etc/passwd -> Admin password\n"); + fprintf(stderr, "mkpasswd: --password must not be empty\n"); return 1; } @@ -544,35 +541,30 @@ int main(int argc, char **argv) return 1; } - /* Reject the well-known default password. The build system should have - * caught this already; mkpasswd is the last line of defence. - */ + /* Warn if the board Kconfig default password is still being used. */ if (strcmp(password, "Administrator") == 0) { fprintf(stderr, - "mkpasswd: ERROR: password \"Administrator\" is not allowed.\n" - " Set a unique password in menuconfig: Board Selection -> " - "Auto-generate /etc/passwd -> Admin password\n"); - return 1; + ">>>> WARNING: YOU ARE USING THE DEFAULT ADMIN PASSWORD " + "(CONFIG_BOARD_ETC_ROMFS_" + "PASSWD_PASSWORD=\"Administrator\")!!! PLEASE CHANGE " + "IT!!! <<<<\n"); } - /* Reject the default TEA keys. Using the published defaults means any - * attacker who has a copy of the NuttX source can decrypt the password - * hash directly from the firmware image (CWE-321). + /* Warn when the user has not changed the default TEA keys. + * The default values are identical across all NuttX builds, so any + * attacker with access to the firmware image can recover the plaintext + * password. This is a warning only; the build is not aborted. */ if (key[0] == DEFAULT_KEY1 && key[1] == DEFAULT_KEY2 && key[2] == DEFAULT_KEY3 && key[3] == DEFAULT_KEY4) { fprintf(stderr, - "mkpasswd: ERROR: default TEA encryption keys " - "are not allowed.\n" - " Set keys in menuconfig: Application Configuration -> " - "File System Utilities -> Password file support\n" - " Or enable random key generation under Board Selection -> " - "Auto-generate /etc/passwd\n"); - return 1; + ">>>> WARNING: YOU ARE USING DEFAULT PASSWORD KEYS " + "(CONFIG_FSUTILS_" + "PASSWD_KEY1-4)!!! PLEASE CHANGE IT!!! <<<<\n"); } /* Encrypt the password using TEA + custom base64. diff --git a/tools/passwd_keys.mk b/tools/passwd_keys.mk deleted file mode 100644 index 8817f0ddb56..00000000000 --- a/tools/passwd_keys.mk +++ /dev/null @@ -1,74 +0,0 @@ -############################################################################ -# tools/passwd_keys.mk -# -# SPDX-License-Identifier: Apache-2.0 -# -# Passwd / TEA-key validation and generation. Included from the top-level -# Makefile immediately after .config is loaded, BEFORE tools/Unix.mk builds -# include/nuttx/config.h. This ordering guarantees that freshly generated -# keys are present in .config when config.h is created, so the firmware and -# mkpasswd always agree on the same key values in a single make invocation. -# -# Board.mk only consumes CONFIG_FSUTILS_PASSWD_KEY1..4 in the ROMFS recipe. -############################################################################ - -TOPDIR ?= . - -# Skip enforcement during configuration-only make invocations (menuconfig, -# olddefconfig, clean_context, etc.) so the user can set the password first. -PASSWD_SKIP_GOALS := config menuconfig oldconfig olddefconfig savedefconfig \ - nconfig qconfig gconfig clean_context apps_preconfig \ - apps_config apps_menuconfig apps_oldconfig apps_olddefconfig \ - apps_savedefconfig apps_nconfig apps_qconfig apps_gconfig \ - distclean clean - -ifeq ($(MAKECMDGOALS),) -_PASSWD_ENFORCE := y -else -_PASSWD_ENFORCE := $(if $(filter-out $(PASSWD_SKIP_GOALS),$(MAKECMDGOALS)),y,) -endif - -ifeq ($(CONFIG_BOARD_ETC_ROMFS_PASSWD_ENABLE),y) -ifeq ($(_PASSWD_ENFORCE),y) - -# --- password check --- -ifeq ($(strip $(patsubst "%",%,$(CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD))),) -$(info ) -$(info BUILD ERROR: Admin password not set.) -$(info ) -$(info Run make menuconfig and set:) -$(info Board Selection -> Auto-generate /etc/passwd -> Admin password) -$(info ) -$(info For TEA keys, either enable random generation in the same menu,) -$(info or set CONFIG_FSUTILS_PASSWD_KEY1..4 under Application Configuration) -$(info -> File System Utilities -> Password file support.) -$(info ) -$(info Password and keys are not saved in defconfig.) -$(info ) -$(error Aborting: CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD is not set) -endif - -# --- TEA key check / generation --- -_PASSWD_KEYS_NEED_SETUP := $(shell \ - $(TOPDIR)/tools/check_passwd_keys.sh $(TOPDIR)/.config 2>/dev/null) - -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 ) -$(info BUILD ERROR: TEA encryption keys not configured.) -$(info ) -$(info Run make menuconfig and either:) -$(info - enable Generate random TEA keys automatically, or) -$(info - set CONFIG_FSUTILS_PASSWD_KEY1..4 under Application Configuration) -$(info -> File System Utilities -> Password file support) -$(info ) -$(error Aborting: CONFIG_FSUTILS_PASSWD_KEY1..4 must be set to non-default values) -endif -endif -endif - -endif
