/* * (C) Copyright 2000 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * * SPDX-License-Identifier: GPL-2.0+ */ /* #define DEBUG */ #include #include #include #include #include #ifdef CONFIG_NM_LOGIN #include #include #include #include /* Set defaults for passwd file location */ #ifndef CONFIG_NM_LOGIN_PART #define CONFIG_NM_LOGIN_PART "1:3" #endif #ifndef CONFIG_NM_LOGIN_PASSWD #define CONFIG_NM_LOGIN_PASSWD "/root/boot/bootpass" #endif #endif DECLARE_GLOBAL_DATA_PTR; /* * Board-specific Platform code can reimplement show_boot_progress () if needed */ __weak void show_boot_progress(int val) {} #ifdef CONFIG_NM_LOGIN /**************************************************************************** * check if ubootpwd exists in data partition and perform a login, * otherwise continue booting */ int login (void) { #define MAX_TRIES_ENTER 4096 #define PASSWORD_LEN 256 char stored_pw_hash[PASSWORD_LEN]; char password[PASSWORD_LEN]; int res, i, tries; int legacy_md5 = 0; loff_t actread; char c; puts("\nautoboot has been stopped, press 'e' to enter: "); for (i=0; i<=MAX_TRIES_ENTER; i++) { c = getc(); if (c == 'e' || c == '\n') { puts("e"); break; } /* Enter condition not given -> restart */ if (i == MAX_TRIES_ENTER) return 0; } puts("\n"); /* Try to get password hash file */ memset(stored_pw_hash, 0x0, sizeof(stored_pw_hash)); if (fs_set_blk_dev("mmc", CONFIG_NM_LOGIN_PART, FS_TYPE_EXT) != 0) { puts("Error, can not set blk device\n"); return 1; } res = fs_read(CONFIG_NM_LOGIN_PASSWD, (ulong)stored_pw_hash, 0, sizeof(stored_pw_hash), &actread); if ((res != 0) || (actread <= 0)) { /* no file or hash found -> allow login w/o password */ puts("Login succeeded\n\n"); return 1; } else if (actread == 16) { legacy_md5 = 1; } for (tries = 1; ; tries++) { puts("\nEnter password: "); /* TODO: no backspace ? */ /* TODO: rename buf to something more useful */ /* TODO: print a dot or blind? */ password[0] = 0; for (i=0; i 0) { puts("\n"); if (legacy_md5) { /* MD5 - legacy */ char entered[32]; /* TODO: Why 32, MD5 algo uses only 16 bytes */ md5((unsigned char *)password, strlen(password), (unsigned char *)entered); if (memcmp(stored_pw_hash, entered, 16) == 0) { break; } } else { /* SHA256 */ char *cp = sha_crypt(password, stored_pw_hash); /* TODO: Salt = PW? */ res = memcmp(cp, stored_pw_hash, actread); free(cp); if (res == 0) break; } /* TODO: exponentional delay */ puts("Login incorrect\n"); if (tries == 3) { return 0; } } /* TODO: remove password from memory !!!!! */ memset(password, 0, sizeof(password)); } /* succeeded */ puts("Login succeeded\n\n"); return 1; } #endif /* CONIFG_NM_LOGIN */ /****************************************************************************/ static void run_preboot_environment_command(void) { #ifdef CONFIG_PREBOOT char *p; p = getenv("preboot"); if (p != NULL) { # ifdef CONFIG_AUTOBOOT_KEYED int prev = disable_ctrlc(1); /* disable Control C checking */ # endif run_command_list(p, -1, 0); # ifdef CONFIG_AUTOBOOT_KEYED disable_ctrlc(prev); /* restore Control C checking */ # endif } #endif /* CONFIG_PREBOOT */ } /* We come here after U-Boot is initialised and ready to process commands */ void main_loop(void) { const char *s; bootstage_mark_name(BOOTSTAGE_ID_MAIN_LOOP, "main_loop"); #ifdef CONFIG_VERSION_VARIABLE setenv("ver", version_string); /* set version variable */ #endif /* CONFIG_VERSION_VARIABLE */ cli_init(); run_preboot_environment_command(); #if defined(CONFIG_UPDATE_TFTP) update_tftp(0UL, NULL, NULL); #endif /* CONFIG_UPDATE_TFTP */ s = bootdelay_process(); if (cli_process_fdt(&s)) cli_secure_boot_cmd(s); autoboot_command(s); #ifdef CONFIG_NM_LOGIN if (!login()) { puts ("Login failed, resetting...\n"); do_reset (NULL, 0, 0, NULL); } #endif cli_loop(); panic("No CLI available"); }