u-boot/common/main.c

198 lines
4.1 KiB
C

/*
* (C) Copyright 2000
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* SPDX-License-Identifier: GPL-2.0+
*/
/* #define DEBUG */
#include <common.h>
#include <autoboot.h>
#include <cli.h>
#include <console.h>
#include <version.h>
#ifdef CONFIG_NM_LOGIN
#include <fs.h>
#include <u-boot/md5.h>
#include <malloc.h>
#include <crypt.h>
#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", "1:3", FS_TYPE_EXT) != 0) {
puts("Error, can not set blk device\n");
return 1;
}
res = fs_read("/root/boot/bootpass", (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<PASSWORD_LEN; i++) {
password[i] = getc();
if (password[i] == '\r' || password[i] == '\n') {
password[i] = 0;
break;
}
}
password[PASSWORD_LEN-1] = 0;
if (strlen(password) > 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 {
/* SHA1 */
char *cp = sha_crypt(password, stored_pw_hash); /* TODO: Salt = PW? */
res = memcmp(cp, stored_pw_hash, actread);
free(cp);
if (res == 0)
break;
/*
if (memcmp(cp, stored_pw_hash, actread) == 0) {
free(cp);
break;
}
free(cp);
*/
}
/* 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");
}