This is the mail archive of the ecos-discuss@sourceware.org mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: any existing code about a prompt password for entering redboot ?


On Fri, Mar 31, 2006 at 01:28:27PM +0200, Rainer Arndt wrote:
> Hi Thierry
> 
> I'm starting to work on the same feature. I suggest the following:
> 
> Define a new CDL option. Make the new code dependent on the CDL option.
> The right point to start is main.c from redboot package. Define a new
> redboot command (see RedBoot_cmd macro) which should handle the password
> verification and set a flag if the right password is found.
> 
> Then look at the code after the parse() function call. Allow command handler
> calls (cmd->func)() only if the password flag was set valid from the
> passwort command or if the current cmd even is the password command
> (cmd->str).
> 
> You can use a fixed password defined in a CDL option or use redboot config
> entries to store individual passwords.
> 
> This is a simple solution, but it fulfill my requirements.
> Any comments from the specialists?

So there seems to be more interest than i expect. So here is my code
from a long time ago.

You will need to work on the CDL. I had some local modifications to
make this work and i no longer have the code. It could be in the email
archive.

See the thread

http://sourceware.org/ml/ecos-patches/2002-11/msg00019.html

If i remeber correctly Bart suggested doing it a different way, but
i've not found that discuss thread yet.

        Andrew

//==========================================================================
//
//      passwd.c
//
//      RedBoot Password support
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 2002 Andrew Lunn
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s):    asl
// Contributors: asl
// Date:         2002-10-31
// Purpose:      
// Description:  
//              
// This code is part of RedBoot (tm).
//
//####DESCRIPTIONEND####
//
//==========================================================================

#include "redboot.h"
#include "flash_config.h"

#ifdef CYGBLD_BUILD_REDBOOT_WITH_PASSWORD_ROT13
#include <cyg/encrypt/rot13.h>
#endif

#ifdef CYGBLD_BUILD_REDBOOT_WITH_PASSWORD_FLASH
RedBoot_config_option("Password to Redboot",
                      flash_passwd,
                      ALWAYS_ENABLED, false,
                      CONFIG_STRING,
                      0);

RedBoot_cmd("passwd",
            "Set the password for Redboot",
            "",
            do_passwd
            );
#endif

/* Check the password is valid. There are a few options here.  The
   password we are checking against could be obfusticated with
   ROT13. There are two, mutually exclusive, places the password to
   check against could be. It can be a fixed password in the CDL
   configuration or it can be in flash. CDL controls these two
   options. */
static bool passwd_ok(char * line) 
{
#ifdef CYGBLD_BUILD_REDBOOT_WITH_PASSWORD_ROT13
  int len = strlen(line);
  
  cyg_rot13(line,len);
#endif

#ifdef CYGBLD_BUILD_REDBOOT_WITH_PASSWORD_FIXED
  return (!strcmp(line, CYGDAT_REDBOOT_PASSWD));
#endif

#ifdef CYGBLD_BUILD_REDBOOT_WITH_PASSWORD_FLASH
  {
    char * flash_passwd;
    
    /* If there is no password in flash, we accept anything */
    if (!flash_get_config("QJFFNC",&flash_passwd,CONFIG_STRING)) 
      return true; 
    return (!strcmp(line,flash_passwd));
  }
#endif
  /* Failback in case the CDL goes wrong */
  return true;
}

/* Delay for 2 second after an invalid password. Use the gets routine
   to do the delay, but discard anything typed in. Doing this keeps
   the network alive since the idle processing is performed. */

static void retry_delay(char * line, const int size, const int timeout) 
{
  int timeout_delay_ms = 2000;
  int res;
  
  while (timeout_delay_ms >= timeout) {
    res = _rb_gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT);
    if (res == _GETS_TIMEOUT) {
      timeout_delay_ms -= timeout;
    }
  }
}

/* Repeatedly ask for the password until its correct. Ignore
   everything else including gdb breakins. If the wrong password is
   entered delay for 2 second before doing a retry. */

void get_password(char *line, const int size, const int timeout) 
{
  bool prompt = true;
  bool good_passwd = false;
  int res;
  
  console_echo = false;  /* Don't echo what they user types */
  
  while (!good_passwd) {
    if (prompt) {
      diag_printf("\nRedboot Password> ");
      prompt = false;
    }
    
    res = _rb_gets(line, size, timeout);
    switch (res) {
    case _GETS_OK:
      {
        if (passwd_ok(line)) {
          good_passwd = true;
        } else {
          diag_printf("Sorry. Please try again");
          retry_delay(line,size,timeout);
          prompt = true;
        }
        break;
      }
    case _GETS_CTRLC:
    case _GETS_TIMEOUT:
    case _GETS_GDB:
    case _GETS_PASSWD:  /* Should never happen */
    default:
      break;
    }
  }
  diag_printf("\n");
  
  console_echo = true; /* Turn echo back on so we can see what we are
                          typing */
}

#ifdef CYGBLD_BUILD_REDBOOT_WITH_PASSWORD_FLASH
void
do_passwd(int argc, char *argv[])
{
  char line[32];
  char new_passwd[32];
  int ret;
  bool ok = true;
  struct config_option opt;
  
  console_echo = false;  /* Don't echo what they user types */
  
  diag_printf("Old password:");
  ret = _rb_gets(line,sizeof(line),0);
  if ((ret <= 0) || !passwd_ok(line)) {
    ok = false;
  }
  if (ok) {
    diag_printf("\nNew password:");
    ret = _rb_gets(new_passwd,sizeof(new_passwd),0);
    diag_printf("\nNew password again:");
    ret = _rb_gets(line,sizeof(line),0);
    diag_printf("\n");
    
    if (strcmp(new_passwd,line))
      ok = false;
  }

  console_echo = true; /* Turn echo back on so we can see what we are
                          typing */

  if (ok) {
#ifdef CYGBLD_BUILD_REDBOOT_WITH_PASSWORD_ROT13
    int len = strlen(new_passwd);
  
    cyg_rot13(new_passwd,len);
#endif

    /* Take an apsin now....

       We don't want the password to show up when we do "fconfig -l".
       fconfig only lists configuration information that is
       enabled. So we want our password configuration disabled. The
       disable/enable state of a configuration depends on another
       boolean configuration parameter. It XORs this second parameter
       with the enable_sense flag and if the result is true it is
       disabled. So you can say, im disabled when the other
       configuration is true, or im enabled when the other is true
       etc. So, we just need another boolean configuration value with
       a known fixed value we can use to disable ourselves.

       Now, we don't want this second configuration value listed in
       "fconfig -l" either. So it also needs to be disabled. This time
       its a little easier since this configuration value is a
       bool. It uses itself as the enable key. The value of the key
       does not matter, so long as we know its value. So setting it to
       false, we can then set the enable_sense to true so disabling
       this second key.

       With the second key havin value false, the enable sense of the
       password key should be true to make it disabled.

    */

    opt.type = CONFIG_STRING;
    opt.enable = "DISABLE";
    opt.enable_sense = true;
    opt.key = "QJFFNC";
    opt.dflt = (unsigned long) new_passwd;
    flash_add_config(&opt, false);
    
    opt.type = CONFIG_BOOL;
    opt.key = "DISABLE";
    opt.enable = "DISABLE";
    opt.enable_sense = true;
    opt.dflt = 0;
    flash_add_config(&opt, true);

  } else {
    diag_printf("Sorry");
  }

}

#endif //CYGBLD_REDBOOT_WITH_PASSWORD_FLASH  

Attachment: redboot-passwd.diff
Description: Text document

-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]