Author Topic: Username and/or Password on Telnet?  (Read 11153 times)

Offline dkg

  • Newbie
  • *
  • Posts: 48
    • View Profile
Username and/or Password on Telnet?
« on: November 24, 2009, 04:15:17 PM »
I was looking through the code to see where I might add code to require a username and password on the telnet session. I see a function called fnInitiateLogin that might be the best location for this. I also see a check on the return of this function for a value called DO_PASSWORD_ENTRY. However, it is never set.  I was wondering if anyone had already written code to protect the system. I actually would like password protection for both telnet and serial port access to the debug/maintenance menus.

Thanks,
Dave G.

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3236
    • View Profile
    • uTasker
Re: Username and/or Password on Telnet?
« Reply #1 on: November 24, 2009, 04:54:15 PM »
Hi Dave

There used to be password protection on one or both of these interfaces. I think that it was removed since it was a bit fiddly for evaluation, but the code is mostly intact.

See fnInitiateLogin(), which is called o first contact. It always returns DIRECT_LOGIN, which means don't request credentials.
If you change this to return DO_PASSWORD_ENTRY instead it will then cause credentials to be requested. During password entry there is an echo of **** rather than each character and on entry it is checked against the user name and password contained in the parameters.

There may be some details which need to be corrected or adjusted to suit but it does basically look as though it is fundamentally still in the code.

Regards

Mark

Offline dkg

  • Newbie
  • *
  • Posts: 48
    • View Profile
Re: Username and/or Password on Telnet?
« Reply #2 on: November 24, 2009, 05:11:02 PM »
Hi Mark,

I thought it looked like it was once there. However, it isn't as easy as replacing the return value :( I don't believe that routine should be calling fnLoginSuccess before returning the new value. But I don't see any code that actually handles the login and then calls fnLoginSuccess when done.

I see a series of defines that look like states to traverse during the login process but no code uses these states. Here they are:

#define PASSWORD_IDLE             0
#define START_PASSWORD            1
#define ENTER_USER_NAME           2
#define ENTER_NEW_PASSWORD        3
#define CONFIRM_NEW_PASS          4
#define TELNET_LOGIN              5

Seeing remnants of a login process prompted me to ask about this since I really don't want to reinvent the wheel if it once existed.

Thanks,
Dave G.

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3236
    • View Profile
    • uTasker
Re: Username and/or Password on Telnet?
« Reply #3 on: November 24, 2009, 06:49:09 PM »
Hi Dave

I dug out some old software versions and made a couple of changes so that the TELNET log-in protection works as expected. [due to an otherwise undefined variable I had to also have the serial support active but this is not a problem for you].

1. In fnCommandInput() there was originally just

            fnSaveDebugHandle(iSource);                                  // save present debug handle and set appropriate
            fnDoDebug(cDebugIn, (unsigned char)(ucDebugCnt+1), iSource); // treat debug messages
            fnRestoreDebugHandle();                                      // return the present debug output
            iReturn = 1;                                                 // we will always send something so report that a transmission has been started



I put some code around this as follows

if ((ucPasswordState != PASSWORD_IDLE) && ((usTelnet_state != ES_NETWORK_LOGIN) || (iSource == SOURCE_NETWORK))) {
    int iPassword = 0;
    cDebugIn[ucDebugCnt] = ':';
    while (cDebugIn[iPassword] != ':') {}
    if ((fnVerifyUser(cDebugIn, DO_CHECK_USER_NAME) != 0) || (fnVerifyUser(&cDebugIn[iPassword+1], DO_CHECK_PASSWORD) != 0)) {
        fnDebugMsg("\n\rError - bad credentials!\n\r");
        if (usTelnet_state == ES_NETWORK_LOGIN){
            fnTelnet(Telnet_socket, LEAVE_ECHO_MODE);
            usTelnet_state = ES_TERMINATE_CONNECTION;                    // quit an active Telnet session
        }
    }
    else {
        usTelnet_state = ES_NETWORK_COMMAND_MODE;
        fnTelnet(Telnet_socket, CLEAR_TEXT_ENTRY);                       // make sure telnet echos in clear text mode again
        fnDoAdmin(DO_SHOW_CONFIG, 0);
        ucMenu = 0;                                                      // set main menu
        fnDisplayHelp(0);                                                // display main menu
    }
}
else {
    fnSaveDebugHandle(iSource);                                          // save present debug handle and set appropriate
    fnDoDebug(cDebugIn, (unsigned char)(ucDebugCnt+1), iSource);         // treat debug messages
    fnRestoreDebugHandle();                                              // return the present debug output
    iReturn = 1;                                                         // we will always send something so report that a transmission has been started

}


2. In fnInitiateLogin() I changed the default case from

        usTelnet_state = ES_NETWORK_LOGIN;
        break;


to

        usTelnet_state = ES_NETWORK_LOGIN;
        fnDebugMsg("\n\rPlease enter user name and password (user:pass): ");
        return DO_PASSWORD_ENTRY;


When the TELNET sever connection is made the server requests a password "Please enter user name and password (user:pass):"
It should be entered as "ADMIN:uTasker" if the default user name and password have not been changed.

On failure the connection is terminated after displaying a log-in failure message.
If it is successful the command menu is displayed.

The serial protection is a little different since it doesn't do through the TELNET listener and used its own set of parameters (protection on one or the other possible), but, based on this working case the serial one should be easier to add.

Regards

Mark

« Last Edit: November 24, 2009, 08:04:58 PM by mark »

Offline dkg

  • Newbie
  • *
  • Posts: 48
    • View Profile
Re: Username and/or Password on Telnet?
« Reply #4 on: November 24, 2009, 06:58:41 PM »
Hi Mark,

Thanks for the "old code". :)

I'll give it a try and let you know how it works.

If I make additional changes to make it work, I'll post it here.

Dave G.

Offline dkg

  • Newbie
  • *
  • Posts: 48
    • View Profile
Re: Username and/or Password on Telnet?
« Reply #5 on: November 24, 2009, 11:03:10 PM »
Hi Mark,

I got it to work but with a few additional changes:

  • Added a line to fnInitiateLogin to set the password state away from PASSWORD_IDLE
  • Added a line in fnCommandInput to set the password state back to idle after successful entry.
  • Changed a new line of code in fnCommandInput to prevent an infinite loop.

So the following are the working code snippets. In fnCommandInput:
Code: [Select]
            if ((ucPasswordState != PASSWORD_IDLE) && ((usTelnet_state != ES_NETWORK_LOGIN) || (iSource == SOURCE_NETWORK))) {
                int iPassword = 0;
                cDebugIn[ucDebugCnt] = ':';
                while (cDebugIn[iPassword] != ':') {
                iPassword++;
                }
                if ((fnVerifyUser(cDebugIn, DO_CHECK_USER_NAME) != 0) || (fnVerifyUser(&cDebugIn[iPassword+1], DO_CHECK_PASSWORD) != 0)) {
                    fnDebugMsg("\n\rError - bad credentials!\n\r");
                    if (usTelnet_state == ES_NETWORK_LOGIN){
                        fnTelnet(Telnet_socket, LEAVE_ECHO_MODE);
                        usTelnet_state = ES_TERMINATE_CONNECTION;                    // quit an active Telnet session
                    }
                }
                else {
                    usTelnet_state = ES_NETWORK_COMMAND_MODE;
                    fnTelnet(Telnet_socket, CLEAR_TEXT_ENTRY);                       // make sure telnet echos in clear text mode again
                    ucPasswordState = PASSWORD_IDLE;
                    fnWelcomeMessage();
                    ucMenu = 0;                                                      // set main menu
                    fnDisplayHelp(0);                                                // display main menu
                }
            }
            else {
fnSaveDebugHandle(iSource);                                  // save present debug handle and set appropriate
fnDoDebug(cDebugIn, (unsigned char)(ucDebugCnt+1), iSource); // treat debug messages
fnRestoreDebugHandle();                                      // return the present debug output
iReturn = 1;                                                 // we will always send something so report that a transmission has been started
            }

And the default case in fnIntiateLogin:
Code: [Select]
        usTelnet_state = ES_NETWORK_LOGIN;
        fnDebugMsg("\n\rPlease enter user name and password (user:pass): ");
        ucPasswordState = ENTER_USER_NAME;
        return DO_PASSWORD_ENTRY;
        break;

Regards,
Dave G.

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3236
    • View Profile
    • uTasker
Re: Username and/or Password on Telnet?
« Reply #6 on: November 24, 2009, 11:09:09 PM »
Hi Dave

Thanks for the corrections and reference.

Cheers

Mark