Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:19

0001 /**
0002  * @file
0003  *
0004  * @brief Shell login prompt functions.
0005  */
0006 
0007 /*
0008  * Authorship
0009  * ----------
0010  * Parts of this software was created by
0011  *     Till Straumann <strauman@slac.stanford.edu>, 2003-2007
0012  *         Stanford Linear Accelerator Center, Stanford University.
0013  *
0014  * Acknowledgement of sponsorship
0015  * ------------------------------
0016  * Parts of this software was produced by
0017  *     the Stanford Linear Accelerator Center, Stanford University,
0018  *         under Contract DE-AC03-76SFO0515 with the Department of Energy.
0019  *
0020  * Government disclaimer of liability
0021  * ----------------------------------
0022  * Neither the United States nor the United States Department of Energy,
0023  * nor any of their employees, makes any warranty, express or implied, or
0024  * assumes any legal liability or responsibility for the accuracy,
0025  * completeness, or usefulness of any data, apparatus, product, or process
0026  * disclosed, or represents that its use would not infringe privately owned
0027  * rights.
0028  *
0029  * Stanford disclaimer of liability
0030  * --------------------------------
0031  * Stanford University makes no representations or warranties, express or
0032  * implied, nor assumes any liability for the use of this software.
0033  *
0034  * Stanford disclaimer of copyright
0035  * --------------------------------
0036  * Stanford University, owner of the copyright, hereby disclaims its
0037  * copyright and all other rights in this software.  Hence, anyone may
0038  * freely use it for any purpose without restriction.
0039  *
0040  * Maintenance of notices
0041  * ----------------------
0042  * In the interest of clarity regarding the origin and status of this
0043  * SLAC software, this and all the preceding Stanford University notices
0044  * are to remain affixed to any copy or derivative of this software made
0045  * or distributed by the recipient and are to be affixed to any copy of
0046  * software made or distributed by the recipient that contains a copy or
0047  * derivative of this software.
0048  *
0049  * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
0050  *
0051  * Copyright (c) 2009 embedded brains GmbH & Co. KG
0052  *
0053  * Based on work from Chris Johns, Fernando Ruiz and Till Straumann.
0054  *
0055  * Derived from files "cpukit/libmisc/shell/shell.c" and
0056  * "cpukit/telnetd/check_passwd.c".
0057  *
0058  * The license and distribution terms for this file may be
0059  * found in the file LICENSE in this distribution or at
0060  * http://www.rtems.org/license/LICENSE.
0061  */
0062 
0063 #ifdef HAVE_CONFIG_H
0064 #include "config.h"
0065 #endif
0066 
0067 #include <stdio.h>
0068 #include <termios.h>
0069 #include <unistd.h>
0070 #include <ctype.h>
0071 #include <errno.h>
0072 #include <string.h>
0073 #include <rtems/shell.h>
0074 
0075 static int rtems_shell_discard( int c, FILE *stream)
0076 {
0077   return c;
0078 }
0079 
0080 static bool rtems_shell_get_text(
0081   FILE *in,
0082   FILE *out,
0083   char *line,
0084   size_t size
0085 )
0086 {
0087   int fd_in = fileno( in);
0088   int (*put)( int, FILE *) =
0089     out != NULL && isatty( fd_in)
0090       ? fputc
0091       : rtems_shell_discard;
0092   size_t i = 0;
0093 
0094   if (size < 1) {
0095     return false;
0096   }
0097 
0098   tcdrain( fd_in);
0099   if (out != NULL){
0100     tcdrain( fileno(out) );
0101   }
0102 
0103   while (true) {
0104     int c = fgetc(in);
0105 
0106     switch (c) {
0107       case EOF:
0108         clearerr( in );
0109         return false;
0110       case '\n':
0111       case '\r':
0112         put('\n', out);
0113         line [i] = '\0';
0114         return true;
0115       case  127:
0116       case '\b':
0117         if (i > 0) {
0118           put('\b', out);
0119           put(' ', out);
0120           put('\b', out);
0121           --i;
0122         } else {
0123           put('\a', out);
0124         }
0125         break;
0126       default:
0127         if (!iscntrl( c)) {
0128           if (i < size - 1) {
0129             line [i] = (char) c;
0130             ++i;
0131             put( c, out);
0132           } else {
0133             put('\a', out);
0134           }
0135         } else {
0136           put('\a', out);
0137         }
0138         break;
0139     }
0140   }
0141   return true;
0142 }
0143 
0144 bool rtems_shell_login_prompt(
0145   FILE *in,
0146   FILE *out,
0147   const char *device,
0148   rtems_shell_login_check_t check
0149 )
0150 {
0151   int fd_in = fileno(in);
0152   struct termios termios_previous;
0153   bool restore_termios = false;
0154   int i = 0;
0155   bool result = false;
0156 
0157   if (tcgetattr( fd_in, &termios_previous) == 0) {
0158     struct termios termios_new = termios_previous;
0159 
0160     /*
0161      *  Stay in canonical mode so we can tell EOF and dropped connections.
0162      *  But read one character at a time and do not echo it.
0163      */
0164     termios_new.c_lflag &= (unsigned char) ~ECHO;
0165     termios_new.c_cc [VTIME] = 0;
0166     termios_new.c_cc [VMIN] = 1;
0167 
0168     restore_termios = tcsetattr( fd_in, TCSANOW, &termios_new) == 0;
0169   }
0170 
0171   for (i = 0; i < 3; ++i) {
0172     char user [32];
0173     char passphrase [128];
0174 
0175     fprintf( out, "%s login: ", device );
0176     fflush( out );
0177     result = rtems_shell_get_text( in, out, user, sizeof(user) );
0178     if ( !result )
0179       break;
0180     if (0 == strlen(user))
0181       continue;
0182 
0183     fflush( in);
0184     fprintf( out, "Password: ");
0185     fflush( out);
0186     result = rtems_shell_get_text( in, NULL, passphrase, sizeof(passphrase) );
0187     if ( !result )
0188       break;
0189     fputc( '\n', out);
0190 
0191     result = check( user, passphrase );
0192     if (result)
0193       break;
0194 
0195     fprintf( out, "Login incorrect\n\n");
0196     sleep( 2);
0197   }
0198 
0199   if (restore_termios) {
0200     /* What to do if restoring the flags fails? */
0201     tcsetattr( fd_in, TCSANOW, &termios_previous);
0202   }
0203 
0204   return result;
0205 }