source: rtems/cpukit/libmisc/shell/login_prompt.c @ 2649eef

4.104.11
Last change on this file since 2649eef was 2649eef, checked in by Joel Sherrill <joel.sherrill@…>, on Mar 27, 2009 at 3:31:52 PM

2009-03-27 Sebastian Huber <sebastian.huber@…>

  • Makefile.am, preinstall.am, libmisc/Makefile.am, libmisc/shell/shell.c, libmisc/shell/shell.h, telnetd/check_passwd.c, telnetd/telnetd.c, telnetd/telnetd.h: Generalized login check.
  • libmisc/shell/login.h, libmisc/shell/login_check.c, libmisc/shell/login_prompt.c: New files.
  • libmisc/stackchk/check.c: Changed format for blown stack message.
  • libcsupport/src/libio_sockets.c: Removed superfluous cast.
  • libnetworking/rtems/ftpfs.h: Documentation.
  • Property mode set to 100644
File size: 3.4 KB
Line 
1/**
2 * @file
3 *
4 * @author Sebastian Huber <sebastian.huber@embedded-brains.de>
5 *
6 * @brief Shell login prompt functions.
7 */
8
9/*
10 * Copyright (c) 2009
11 * embedded brains GmbH
12 * Obere Lagerstr. 30
13 * D-82178 Puchheim
14 * Germany
15 * <rtems@embedded-brains.de>
16 *
17 * Based on work from Chris Johns, Fernando Ruiz and Till Straumann.
18 *
19 * The license and distribution terms for this file may be
20 * found in the file LICENSE in this distribution or at
21 * http://www.rtems.com/license/LICENSE.
22 */
23
24#include <stdio.h>
25#include <termios.h>
26#include <unistd.h>
27#include <ctype.h>
28
29#include <rtems/login.h>
30
31static int rtems_shell_discard( int c, FILE *stream)
32{
33  return c;
34}
35
36static void rtems_shell_get_text(
37  FILE *in,
38  FILE *out,
39  char *line,
40  size_t size
41)
42{
43  int fd_in = fileno( in);
44  int (*put)( int, FILE *) =
45    out != NULL && isatty( fd_in)
46      ? fputc
47      : rtems_shell_discard;
48  size_t i = 0;
49
50  if (size < 1) {
51    return;
52  }
53
54  tcdrain( fd_in);
55  if (out != NULL){
56    tcdrain( fileno( out));
57  }
58
59  while (true) {
60    int c = fgetc( in);
61
62    switch (c) {
63      case EOF:
64        /* Here comes an ugly hack: The Termios driver's read() handler returns
65         * 0 to the C library's fgets() if it times out.  fgets() interprets
66         * this (correctly) as EOF, a condition we want to undo since it's not
67         * really true since we really have a read error (Termios bug?).
68         *
69         * As a workaround we push something back and read it again.  This
70         * should simply reset the EOF condition.
71         */
72        if (ungetc( '?', in) == '?') {
73          fgetc( in);
74        }
75        break;
76      case '\n':
77      case '\r':
78        put( '\n', out);
79        line [i] = '\0';
80        return;
81      case  127:
82      case '\b':
83        if (i > 0) {
84          put( '\b', out);
85          put( ' ', out);
86          put( '\b', out);
87          --i;
88        } else {
89          put( '\a', out);
90        }
91        break;
92      default:
93        if (!iscntrl( c)) {
94          if (i < size - 1) {
95            line [i] = (char) c;
96            ++i;
97            put( c, out);
98          } else {
99            put( '\a', out);
100          }
101        } else {
102          put( '\a', out);
103        }
104        break;
105    }
106  }
107}
108
109bool rtems_shell_login_prompt(
110  FILE *in,
111  FILE *out,
112  const char *device,
113  rtems_login_check check
114)
115{
116  int fd_in = fileno( in);
117  struct termios termios_previous;
118  bool restore_termios = false;
119  int i = 0;
120  bool result = false;
121
122  if (tcgetattr( fd_in, &termios_previous) == 0) {
123    struct termios termios_new = termios_previous;
124
125    termios_new.c_lflag &= ~ECHO;
126    termios_new.c_lflag &= ~ICANON;
127    termios_new.c_cc [VTIME] = 255;
128    termios_new.c_cc [VMIN] = 0;
129
130    restore_termios = tcsetattr( fd_in, TCSANOW, &termios_new) == 0;
131  }
132
133  for (i = 0; i < 3; ++i) {
134    char user [32];
135    char passphrase [128];
136
137    fprintf( out, "%s login: ", device);
138    fflush( out);
139    rtems_shell_get_text( in, out, user, sizeof( user));
140
141    fflush( in);
142    fprintf( out, "Password: ");
143    fflush( out);
144    rtems_shell_get_text( in, NULL, passphrase, sizeof( passphrase));
145    fputc( '\n', out);
146
147    result = check( user, passphrase);
148    if (result) {
149      break;
150    }
151
152    fprintf( out, "Login incorrect\n\n");
153    sleep( 2);
154  }
155
156  if (restore_termios) {
157    /* What to do if restoring the flags fails? */
158    tcsetattr( fd_in, TCSANOW, &termios_previous);
159  }
160
161  return result;
162}
Note: See TracBrowser for help on using the repository browser.