Changeset 8a775c27 in rtems


Ignore:
Timestamp:
Mar 27, 2009, 1:45:31 PM (11 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.10, 4.11, master
Children:
2649eef
Parents:
8916bdc7
Message:

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.
Location:
cpukit
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • cpukit/ChangeLog

    r8916bdc7 r8a775c27  
     12009-03-27      Sebastian Huber <sebastian.huber@embedded-brains.de>
     2
     3        * Makefile.am, preinstall.am, libmisc/Makefile.am,
     4        libmisc/shell/shell.c, libmisc/shell/shell.h, telnetd/check_passwd.c,
     5        telnetd/telnetd.c, telnetd/telnetd.h:
     6        Generalized login check.
     7        * libmisc/shell/login.h, libmisc/shell/login_check.c,
     8        libmisc/shell/login_prompt.c: New files.
     9        * libmisc/stackchk/check.c: Changed format for blown stack message.
     10        * libcsupport/src/libio_sockets.c: Removed superfluous cast.
     11        * libnetworking/rtems/ftpfs.h: Documentation.
     12
    1132009-03-26      Sebastian Huber <sebastian.huber@embedded-brains.de>
    214
  • cpukit/Makefile.am

    r8916bdc7 r8a775c27  
    126126## shell
    127127if LIBSHELL
    128 include_rtems_HEADERS += libmisc/shell/shell.h libmisc/shell/shellconfig.h
     128include_rtems_HEADERS += libmisc/shell/shell.h libmisc/shell/shellconfig.h \
     129  libmisc/shell/login.h
    129130endif
    130131
  • cpukit/libcsupport/src/libio_sockets.c

    r8916bdc7 r8a775c27  
    7171  iop->data0 = fd;
    7272  iop->data1 = so;
    73   iop->handlers = (rtems_filesystem_file_handlers_r *) h;
     73  iop->handlers = h;
    7474  return fd;
    7575}
  • cpukit/libmisc/Makefile.am

    r8916bdc7 r8a775c27  
    8686    shell/verrx.c shell/vwarn.c shell/vwarnx.c shell/warn.c shell/warnx.c \
    8787    shell/fts.c shell/print_heapinfo.c shell/main_wkspaceinfo.c \
    88     shell/shell_script.c
     88    shell/shell_script.c shell/login_prompt.c shell/login_check.c
    8989if LIBNETWORKING
    9090libshell_a_SOURCES += shell/main_mount_ftp.c shell/main_mount_tftp.c \
  • cpukit/libmisc/shell/shell.c

    r8916bdc7 r8a775c27  
    4141#include <pwd.h>
    4242
    43 rtems_shell_env_t  rtems_global_shell_env = {
     43rtems_shell_env_t rtems_global_shell_env = {
    4444  .magic         = rtems_build_name('S', 'E', 'N', 'V'),
    4545  .devname       = CONSOLE_DEVICE_NAME,
     
    5454  .output_append = false,
    5555  .wake_on_end   = RTEMS_ID_NONE,
    56   .login         = true
     56  .login_check   = NULL
    5757};
    5858
     
    119119  int          cmd = -1;
    120120  int          inserting = 1;
    121  
     121
    122122  output = (out && isatty(fileno(in)));
    123123
    124124  col = last_col = 0;
    125  
     125
    126126  tcdrain(fileno(in));
    127127  if (out)
     
    130130  if (output && prompt)
    131131    fprintf(out, "\r%s", prompt);
    132  
     132
    133133  line[0] = 0;
    134134  new_line[0] = 0;
    135  
     135
    136136  for (;;) {
    137    
     137
    138138    if (output)
    139139      fflush(out);
     
    143143    if (extended_key == EOF)
    144144      return -2;
    145    
     145
    146146    c = extended_key & RTEMS_SHELL_KEYS_NORMAL_MASK;
    147    
     147
    148148    /*
    149149     * Make the extended_key usable as a boolean.
    150150     */
    151151    extended_key &= ~RTEMS_SHELL_KEYS_NORMAL_MASK;
    152    
     152
    153153    up = 0;
    154    
     154
    155155    if (extended_key)
    156156    {
     
    200200          /* drop through */
    201201        case RTEMS_SHELL_KEYS_DARROW:
    202          
     202
    203203        {
    204204          int last_cmd = cmd;
     
    207207          if (prompt)
    208208            clen += strlen(prompt);
    209          
     209
    210210          if (up) {
    211211            cmd++;
     
    227227          else
    228228            memcpy (line, cmds[cmd], size);
    229          
     229
    230230          col = strlen (line);
    231          
     231
    232232          if (output) {
    233233            fprintf(out,"\r%*c", clen, ' ');
     
    272272          col = 0;
    273273          break;
    274          
     274
    275275        case 5:/*Control-e*/
    276276          if (output)
     
    291291          }
    292292          break;
    293          
     293
    294294        case 0x04:/*Control-d*/
    295295          if (strlen(line))
     
    299299            fputc('\n', out);
    300300          return -2;
    301        
     301
    302302        case '\f':
    303303          if (output) {
     
    335335          if (output)
    336336            fprintf(out,"\n");
    337          
     337
    338338          /*
    339339           * Only process the command if we have a command and it is not
     
    379379}
    380380
    381 int rtems_shell_scanline(
    382   char *line,
    383   int   size,
    384   FILE *in,
    385   FILE *out
    386 )
    387 {
    388   int c;
    389   int col;
    390   int doEcho;
    391 
    392   doEcho = (out && isatty(fileno(in)));
    393 
    394   col = 0;
    395   if (*line) {
    396     col = strlen(line);
    397     if (doEcho) fprintf(out,"%s",line);
    398   }
    399   tcdrain(fileno(in));
    400   if (out)
    401     tcdrain(fileno(out));
    402   for (;;) {
    403     line[col] = 0;
    404     c = fgetc(in);
    405     switch (c) {
    406       case EOF:
    407         return 0;
    408       case '\n':
    409       case '\r':
    410         if (doEcho)
    411           fputc('\n',out);
    412         return 1;
    413       case  127:
    414       case '\b':
    415         if (col) {
    416           if (doEcho) {
    417             fputc('\b',out);
    418             fputc(' ',out);
    419             fputc('\b',out);
    420           }
    421           col--;
    422         } else {
    423           if (doEcho) fputc('\a',out);
    424         }
    425         break;
    426      default:
    427        if (!iscntrl(c)) {
    428          if (col<size-1) {
    429             line[col++] = c;
    430             if (doEcho) fputc(c,out);
    431           } else {
    432             if (doEcho) fputc('\a',out);
    433           }
    434        } else {
    435         if (doEcho)
    436           if (c=='\a') fputc('\a',out);
    437        }
    438        break;
    439      }
    440   }
    441 }
    442  
    443381/* ----------------------------------------------- *
    444382 * - The shell TASK
     
    474412}
    475413
    476 int rtems_shell_login(FILE * in,FILE * out) {
     414static bool rtems_shell_login(FILE * in,FILE * out) {
    477415  FILE          *fd;
    478416  int            c;
     
    585523  }
    586524
    587   times=0;
    588   strcpy(name,"");
    589   strcpy(pass,"");
    590   for (;;) {
    591     times++;
    592     if (times>3) break;
    593     if (out) fprintf(out,"\nlogin: ");
    594     if (!rtems_shell_scanline(name,sizeof(name),in,out )) break;
    595     if (out) fprintf(out,"Password: ");
    596     if (!rtems_shell_scanline(pass,sizeof(pass),in,NULL)) break;
    597     if (out) fprintf(out,"\n");
    598     if ((passwd=getpwnam(name))) {
    599       if (strcmp(passwd->pw_passwd,"!")) { /* valid user */
    600         setuid(passwd->pw_uid);
    601         setgid(passwd->pw_gid);
    602         rtems_current_user_env->euid =
    603         rtems_current_user_env->egid = 0;
    604         chown(rtems_current_shell_env->devname,passwd->pw_uid,0);
    605         rtems_current_user_env->euid = passwd->pw_uid;
    606         rtems_current_user_env->egid = passwd->pw_gid;
    607         if (!strcmp(passwd->pw_passwd,"*")) {
    608           /* /etc/shadow */
    609           return 0;
    610         } else {
    611           /* crypt() */
    612           return 0;
    613         }
    614       }
    615     }
    616     if (out)
    617       fprintf(out,"Login incorrect\n");
    618     strcpy(name,"");
    619     strcpy(pass,"");
    620   }
    621   return -1;
     525  return rtems_shell_login_prompt(
     526    in,
     527    out,
     528    rtems_current_shell_env->devname,
     529    rtems_current_shell_env->login_check
     530  );
    622531}
    623532
     
    687596  shell_env =
    688597  rtems_current_shell_env = rtems_shell_init_env( shell_env_arg );
    689  
     598
    690599  /*
    691600   * @todo chrisj
     
    712621  fileno(stdout);
    713622
    714   /* fprintf( stderr, 
     623  /* fprintf( stderr,
    715624     "-%s-%s-\n", shell_env->input, shell_env->output );
    716625  */
     
    733642    }
    734643  }
    735  
     644
    736645  if (shell_env->input && strcmp(shell_env_arg->input, "stdin") != 0) {
    737646    FILE *input = fopen(shell_env_arg->input, "r");
     
    773682
    774683  rtems_shell_initialize_command_set();
    775  
     684
    776685  /*
    777686   * Allocate the command line buffers.
     
    781690    fprintf(stderr, "no memory for command line buffers\n" );
    782691  }
    783  
     692
    784693  cmds[0] = calloc (cmd_count, RTEMS_SHELL_CMD_SIZE);
    785694  if (!cmds[0]) {
     
    794703      cmds[cmd] = cmds[cmd - 1] + RTEMS_SHELL_CMD_SIZE;
    795704    }
    796    
     705
    797706    do {
    798707      /* Set again root user and root filesystem, side effect of set_priv..*/
     
    809718       *  keep on trucking.
    810719       */
    811       if (shell_env->login) {
    812         result = rtems_shell_login(stdin,stdout) == 0;
     720      if (shell_env->login_check != NULL) {
     721        result = rtems_shell_login(stdin,stdout);
    813722      } else {
    814723        result = true;
     
    830739        else
    831740          chdir("/"); /* XXX: chdir to getpwent homedir */
    832        
     741
    833742        shell_env->exit_shell = false;
    834743
    835744        for (;;) {
    836745          int cmd;
    837          
     746
    838747          /* Prompt section */
    839748          if (prompt) {
     
    841750                                   RTEMS_SHELL_PROMPT_SIZE);
    842751          }
    843        
     752
    844753          /* getcmd section */
    845754          cmd = rtems_shell_line_editor(cmds, cmd_count,
     
    849758          if (cmd == -1)
    850759            continue; /* empty line */
    851          
     760
    852761          if (cmd == -2)
    853762            break; /*EOF*/
     
    857766          if (shell_env->echo)
    858767            fprintf(stdout, "%d: %s\n", line, cmds[cmd]);
    859          
     768
    860769          /* evaluate cmd section */
    861770          c = cmds[cmd];
     
    945854  bool                 forever,
    946855  bool                 wait,
    947   const char*          input,
    948   const char*          output,
     856  const char          *input,
     857  const char          *output,
    949858  bool                 output_append,
    950859  rtems_id             wake_on_end,
    951860  bool                 echo,
    952   bool                 login
     861  rtems_login_check    login_check
    953862)
    954863{
     
    992901  shell_env->output_append = output_append;
    993902  shell_env->wake_on_end   = wake_on_end;
    994   shell_env->login         = login;
     903  shell_env->login_check   = login_check;
    995904
    996905  getcwd(shell_env->cwd, sizeof(shell_env->cwd));
     
    1018927  bool                 forever,
    1019928  bool                 wait,
    1020   bool                 login
     929  rtems_login_check    login_check
    1021930)
    1022931{
     
    1038947    to_wake,                 /* wake_on_end */
    1039948    false,                   /* echo */
    1040     login                    /* login */
     949    login_check              /* login check */
    1041950  );
    1042951}
     
    1061970      return sc;
    1062971  }
    1063  
     972
    1064973  sc = rtems_shell_run(
    1065974    task_name,       /* task_name */
     
    1074983    current_task,    /* wake_on_end */
    1075984    echo,            /* echo */
    1076     false            /* login */
     985    NULL             /* login check */
    1077986  );
    1078987  if (sc != RTEMS_SUCCESSFUL)
  • cpukit/libmisc/shell/shell.h

    r8916bdc7 r8a775c27  
    2525#include <rtems/fs.h>
    2626#include <rtems/libio.h>
     27#include <rtems/login.h>
    2728
    2829#ifdef __cplusplus
     
    100101int rtems_shell_make_args(
    101102  char  *commandLine,
    102   int   *argc_p, 
    103   char **argv_p, 
     103  int   *argc_p,
     104  char **argv_p,
    104105  int    max_args
    105 );
    106 
    107 int rtems_shell_scanline(
    108   char *line,
    109   int   size,
    110   FILE *in,
    111   FILE *out
    112106);
    113107
     
    136130 * @param forever Repeat logins.
    137131 * @param wait Caller should block until shell exits.
    138  * @param login Demand user login.
     132 * @param login_check User login check function, NULL disables login checks.
    139133 *
    140134 */
     
    146140  bool                 forever,
    147141  bool                 wait,
    148   bool                 login
     142  rtems_login_check    login_check
    149143);
    150144
     
    180174
    181175typedef struct  {
    182   rtems_name  magic; /* 'S','E','N','V': Shell Environment */
    183   const char *devname;
    184   const char *taskname;
     176  rtems_name         magic; /* 'S','E','N','V': Shell Environment */
     177  const char        *devname;
     178  const char        *taskname;
    185179  /* user extensions */
    186   bool        exit_shell; /* logout */
    187   bool        forever   ; /* repeat login */
    188   int         errorlevel;
    189   bool        echo;
    190   char        cwd[256];
    191   const char* input;
    192   const char* output;
    193   bool        output_append;
    194   rtems_id    wake_on_end;
    195   bool        login;
     180  bool               exit_shell; /* logout */
     181  bool               forever; /* repeat login */
     182  int                errorlevel;
     183  bool               echo;
     184  char               cwd[256];
     185  const char        *input;
     186  const char        *output;
     187  bool               output_append;
     188  rtems_id           wake_on_end;
     189  rtems_login_check  login_check;
    196190} rtems_shell_env_t;
    197191
     
    211205 * networking stack into the applcation and this may not be
    212206 * required.
    213  */ 
     207 */
    214208struct rtems_shell_filesystems_tt;
    215209typedef struct rtems_shell_filesystems_tt rtems_shell_filesystems_t;
  • cpukit/libmisc/stackchk/check.c

    r8916bdc7 r8a775c27  
    206206 *        the following message out.
    207207 */
    208 void Stack_check_report_blown_task(
    209   Thread_Control *running,
    210   bool         pattern_ok
    211 )
     208void Stack_check_report_blown_task(Thread_Control *running, bool pattern_ok)
    212209{
    213210  Stack_Control *stack = &running->Start.Initial_stack;
    214 
     211  char *pattern_area = Stack_check_Get_pattern_area(stack);
     212  char name [32];
     213
     214  printk("BLOWN STACK!!!\n");
     215  printk("task control block: 0x%08lx\n", (unsigned long) running);
     216  printk("task ID: 0x%08lx\n", (unsigned long) running->Object.id);
    215217  printk(
    216     "BLOWN STACK!!! Offending task(0x%p): "
    217         "id=0x%08" PRIx32 "; name=0x%08" PRIx32,
    218     running,
    219     running->Object.id,
    220     running->Object.name.name_u32
     218    "task name: 0x%08lx\n",
     219    (unsigned long) running->Object.name.name_u32
    221220  );
     221  printk(
     222    "task name string: %s\n",
     223    rtems_object_get_name(running->Object.id, sizeof(name), name)
     224  );
     225  printk(
     226    "task stack area (%lu Bytes): 0x%08lx .. 0x%08lx\n",
     227    (unsigned long) stack->size,
     228    (unsigned long) stack->area,
     229    (unsigned long) ((char *) stack->area + stack->size)
     230  );
     231  if (!pattern_ok) {
     232    printk(
     233      "damaged pattern area (%lu Bytes): 0x%08lx .. 0x%08lx\n",
     234      (unsigned long) PATTERN_SIZE_BYTES,
     235      (unsigned long) pattern_area,
     236      (unsigned long) (pattern_area + PATTERN_SIZE_BYTES)
     237    );
     238  }
    222239
    223240  #if defined(RTEMS_MULTIPROCESSING)
    224241    if (rtems_configuration_get_user_multiprocessing_table()) {
    225242      printk(
    226         "; node=%d",
    227         rtems_configuration_get_user_multiprocessing_table()->node
     243        "node: 0x%08lx\n",
     244        (unsigned long)
     245          rtems_configuration_get_user_multiprocessing_table()->node
    228246      );
    229247    }
    230248  #endif
    231249
    232   printk(
    233     "\n  stack covers range 0x%p - 0x%p (%d bytes)\n",
    234     stack->area,
    235     stack->area + stack->size - 1,
    236     stack->size
    237   );
    238 
    239   if ( !pattern_ok ) {
    240     printk(
    241       "  Damaged pattern begins at 0x%08lx and is %d bytes long\n",
    242       (unsigned long) Stack_check_Get_pattern_area(stack),
    243       PATTERN_SIZE_BYTES);
    244   }
    245 
    246   rtems_fatal_error_occurred( 0x81 );
     250  rtems_fatal_error_occurred(0x81);
    247251}
    248252
  • cpukit/libnetworking/rtems/ftpfs.h

    r8916bdc7 r8a775c27  
    5757 * directory of the server) on a server named @c host using the user name
    5858 * @c user and the password @c pw you must specify the following path:
    59  *
    60  * @c /FTP/user:pw@host/dir/file.txt
     59 * <tt>/FTP/user:pw@@host/dir/file.txt</tt>.
    6160 *
    6261 * If the server is the default server specified in BOOTP, it can be ommitted:
    63  *
    64  * @c /FTP/user:pw/dir/file.txt
     62 * <tt>/FTP/user:pw/dir/file.txt</tt>.
    6563 *
    6664 * The user name will be used for the password if it is ommitted:
    67  *
    68  * @c /FTP/user@host/dir/file.txt
     65 * <tt>/FTP/user@@host/dir/file.txt</tt>.
    6966 *
    7067 * For the data transfer passive (= default) and active (= fallback) mode are
  • cpukit/preinstall.am

    r8916bdc7 r8a775c27  
    238238        $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/shellconfig.h
    239239PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/shellconfig.h
     240
     241$(PROJECT_INCLUDE)/rtems/login.h: libmisc/shell/login.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
     242        $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/login.h
     243PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/login.h
    240244endif
    241245$(PROJECT_INCLUDE)/rtems/libi2c.h: libi2c/libi2c.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
  • cpukit/telnetd/check_passwd.c

    r8916bdc7 r8a775c27  
    11/* $Id$ */
    22
    3 /* Read a password, encrypt it and compare to the encrypted
    4  * password in the TELNETD_PASSWD environment variable.
    5  * No password is required if TELNETD_PASSWD is unset
    6  */
    7 
    8 /*
     3/*
    94 * Authorship
    105 * ----------
     
    127 *     Till Straumann <strauman@slac.stanford.edu>, 2003-2007
    138 *         Stanford Linear Accelerator Center, Stanford University.
    14  * 
     9 *
    1510 * Acknowledgement of sponsorship
    1611 * ------------------------------
     
    1813 *     the Stanford Linear Accelerator Center, Stanford University,
    1914 *         under Contract DE-AC03-76SFO0515 with the Department of Energy.
    20  * 
     15 *
    2116 * Government disclaimer of liability
    2217 * ----------------------------------
     
    2722 * disclosed, or represents that its use would not infringe privately owned
    2823 * rights.
    29  * 
     24 *
    3025 * Stanford disclaimer of liability
    3126 * --------------------------------
    3227 * Stanford University makes no representations or warranties, express or
    3328 * implied, nor assumes any liability for the use of this software.
    34  * 
     29 *
    3530 * Stanford disclaimer of copyright
    3631 * --------------------------------
    3732 * Stanford University, owner of the copyright, hereby disclaims its
    3833 * copyright and all other rights in this software.  Hence, anyone may
    39  * freely use it for any purpose without restriction. 
    40  * 
     34 * freely use it for any purpose without restriction.
     35 *
    4136 * Maintenance of notices
    4237 * ----------------------
     
    4742 * software made or distributed by the recipient that contains a copy or
    4843 * derivative of this software.
    49  * 
     44 *
    5045 * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
    51  */
     46 *
     47 * Copyright (c) 2009
     48 * embedded brains GmbH
     49 * Obere Lagerstr. 30
     50 * D-82178 Puchheim
     51 * Germany
     52 * <rtems@embedded-brains.de>
     53 *
     54 * Modified by Sebastian Huber <sebastian.huber@embedded-brains.de>.
     55 *
     56 * The license and distribution terms for this file may be
     57 * found in the file LICENSE in this distribution or at
     58 * http://www.rtems.com/license/LICENSE.
     59 */
    5260
    53 #if !defined(INSIDE_TELNETD) && !defined(__rtems__)
    54 #include <crypt.h>
    55 #endif
    5661#include <termios.h>
    5762#include <errno.h>
     
    6267#include <syslog.h>
    6368
     69#include <rtems/telnetd.h>
     70
    6471#include "passwd.h"
    6572
    66 /* rtems has global filedescriptors but per-thread stdio streams... */
    67 #define STDI_FD fileno(stdin)
    68 #define MAXPASSRETRY    3
     73char *__des_crypt_r( const char *, const char *, char *, int);
    6974
    70 extern char *__des_crypt_r(char *, char*, char*, int);
     75/**
     76 * @brief Standard Telnet login check that uses DES to encrypt the passphrase.
     77 *
     78 * Takes a @a passphrase, encrypts it and compares it to the encrypted
     79 * passphrase in the @c TELNETD_PASSWD environment variable.  No password is
     80 * required if @c TELNETD_PASSWD is unset.  The argument @a user is ignored.
     81 */
     82bool rtems_telnetd_login_check(
     83  const char *user,
     84  const char *passphrase
     85)
     86{
     87  char *pw = getenv( "TELNETD_PASSWD");
     88  char cryptbuf [21];
     89  char salt [3];
    7190
    72 #if !defined(INSIDE_TELNETD)
    73 #define sockpeername(s,b,sz) (-1)
    74 #endif
    75 
    76 #if defined(INSIDE_TELNETD)
    77 static
    78 #endif
    79 int check_passwd(char *peername)
    80 {
    81   char                  *pw;
    82   int                   rval = -1, tmp, retries;
    83   struct termios        t,told;
    84   int                   restore_flags = 0;
    85   char                  buf[30], cryptbuf[21];
    86   char                  salt[3];
    87 
    88   if ( !(pw=getenv("TELNETD_PASSWD")) || 0 == strlen(pw) )
    89 #ifdef TELNETD_DEFAULT_PASSWD
    90     pw = TELNETD_DEFAULT_PASSWD;
    91 #else
    92     return 0;
    93 #endif
    94 
    95   if ( tcgetattr(STDI_FD, &t) ) {
    96     perror("check_passwd(): tcgetattr");
    97     goto done; 
    98   }
    99   told = t;
    100   t.c_lflag &= ~ECHO;
    101   t.c_lflag &= ~ICANON;
    102   t.c_cc[VTIME] = 255;
    103   t.c_cc[VMIN]  = 0;
    104 
    105   strncpy(salt,pw,2);
    106   salt[2]=0;
    107 
    108   if ( tcsetattr(STDI_FD, TCSANOW, &t) ) {
    109     perror("check_passwd(): tcsetattr");
    110     goto done; 
    111   }
    112   restore_flags = 1;
    113 
    114   /* Here we ask for the password... */
    115   for ( retries = MAXPASSRETRY; retries > 0; retries-- ) {
    116     fflush(stdin);
    117     fprintf(stderr,"Password:");
    118     fflush(stderr);
    119     if ( 0 == fgets(buf,sizeof(buf),stdin) ) {
    120       /* Here comes an ugly hack:
    121        * The termios driver's 'read()' handler
    122        * returns 0 to the c library's fgets if
    123        * it times out. 'fgets' interprets this
    124        * (correctly) as EOF, a condition we want
    125        * to undo since it's not really true since
    126        * we really have a read error (termios bug??)
    127        *
    128        * As a workaround we push something back and
    129        * read it again. This should simply reset the
    130        * EOF condition.
    131        */
    132       if (ungetc('?',stdin) >= 0)
    133         fgetc(stdin);
    134       goto done;
    135     }
    136     fputc('\n',stderr);
    137     tmp = strlen(buf);
    138     while ( tmp > 0 && ('\n' == buf[tmp-1] || '\r' == buf[tmp-1]) ) {
    139       buf[--tmp]=0;
    140     }
    141     if ( !strcmp(__des_crypt_r(buf, salt, cryptbuf, sizeof(cryptbuf)), pw) ) {
    142       rval = 0;
    143       break;
    144     }
    145     fprintf(stderr,"Incorrect Password.\n");
    146     sleep(2);
     91  if (pw == NULL || strlen( pw) == 0) {
     92    #ifdef TELNETD_DEFAULT_PASSWD
     93      pw = TELNETD_DEFAULT_PASSWD;
     94    #else
     95      return true;
     96    #endif
    14797  }
    14898
    149   if ( 0 == retries ) {
    150     syslog( LOG_AUTHPRIV | LOG_WARNING,
    151       "telnetd: %i wrong passwords entered from %s",
    152       MAXPASSRETRY,
    153       peername ? peername : "<UNKNOWN>");
    154   }
     99  strncpy( salt, pw, 2);
     100  salt [2] = '\0';
    155101
    156 done:
    157   /* what to do if restoring the flags fails?? */
    158   if (restore_flags)
    159     tcsetattr(STDI_FD, TCSANOW, &told);
    160  
    161   if (rval) {
    162     sleep(2);
    163   }
    164   return rval;
     102  return strcmp(
     103    __des_crypt_r( passphrase, salt, cryptbuf, sizeof( cryptbuf)),
     104    pw
     105  ) == 0;
    165106}
    166 
    167 #if !defined(INSIDE_TELNETD) && !defined(__rtems__)
    168 int
    169 main(int argc, char **argv)
    170 {
    171 char *str, *enc=0;
    172 int   ch;
    173 
    174 while ( (ch=getopt(argc, argv, "g:")) > 0 ) {
    175   switch (ch) {
    176     default:
    177       fprintf(stderr,"Unknown option\n");
    178     return(1);
    179 
    180     case 'g':
    181       printf("Generated encrypted password: '%s'\n", (enc=crypt(optarg,"td")));
    182     break;
    183      
    184   }
    185 }
    186 if (argc>optind && !enc) {
    187   enc=argv[optind];
    188 }
    189 if (enc) {
    190   str = malloc(strlen(enc) + 30);
    191   sprintf(str,"TELNETD_PASSWD=%s",enc);
    192   putenv(str);
    193 }
    194 if (check_passwd(-1)) {
    195   fprintf(stderr,"check_passwd() failed\n");
    196 }
    197 return 0;
    198 }
    199 
    200 #endif
  • cpukit/telnetd/telnetd.c

    r8916bdc7 r8a775c27  
    66 *  Author: 17,may 2001
    77 *
    8  *   WORK: fernando.ruiz@ctv.es 
     8 *   WORK: fernando.ruiz@ctv.es
    99 *   HOME: correo@fernando-ruiz.com
    1010 *
     
    1616 * With register_telnetd() you add a new command in the shell to start
    1717 * this daemon interactively. (Login in /dev/console of course)
    18  * 
     18 *
    1919 * Sorry but OOB is not still implemented. (This is the first version)
    2020 *
     
    2424 *    program.
    2525 *
    26  *  This program is distributed in the hope that it will be useful,
    27  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    28  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    29  *
    30  *  $Id$
     26 * Copyright (c) 2009
     27 * embedded brains GmbH
     28 * Obere Lagerstr. 30
     29 * D-82178 Puchheim
     30 * Germany
     31 * <rtems@embedded-brains.de>
     32 *
     33 * Modified by Sebastian Huber <sebastian.huber@embedded-brains.de>.
     34 *
     35 * The license and distribution terms for this file may be
     36 * found in the file LICENSE in this distribution or at
     37 * http://www.rtems.com/license/LICENSE.
     38 *
     39 * $Id$
    3140 */
    3241
     
    7483static int sockpeername(int sock, char *buf, int bufsz);
    7584
    76 static int initialize_telnetd(void);
    77 static int telnetd_askForPassword;
    78 
    79 void * telnetd_dflt_spawn(
     85void *telnetd_dflt_spawn(
    8086  const char *name,
    8187  unsigned priority,
     
    8692
    8793/***********************************************************/
    88 rtems_id            telnetd_task_id                 = 0;
    89 uint32_t            telnetd_stack_size              = 32000;
    90 rtems_task_priority telnetd_task_priority           = 0;
    91 bool                telnetd_remain_on_caller_stdio  = false;
    92 void                (*telnetd_shell)(char *, void*) = 0;
    93 void                *telnetd_shell_arg              = NULL;
    94 void *              (*telnetd_spawn_task)(
     94static rtems_id telnetd_task_id = RTEMS_ID_NONE;
     95
     96void *(*telnetd_spawn_task)(
    9597  const char *,
    9698  unsigned,
    9799  unsigned,
    98100  void (*)(void*),
    99   void *) = telnetd_dflt_spawn;
     101  void *
     102) = telnetd_dflt_spawn;
    100103
    101104static char *grab_a_Connection(
     
    179182}
    180183
    181 #if 1
    182 #define INSIDE_TELNETD
    183 #include "check_passwd.c"
    184 #else
    185 #define check_passwd(arg) 0
    186 #endif
    187 
    188 
    189184static void
    190185spawned_shell(void *arg);
     
    204199  if ((des_socket=socket(PF_INET,SOCK_STREAM,0))<0) {
    205200    perror("telnetd:socket");
    206     telnetd_task_id=0;
     201    telnetd_task_id = RTEMS_ID_NONE;
    207202    rtems_task_delete(RTEMS_SELF);
    208203  };
     
    216211    perror("telnetd:bind");
    217212    close(des_socket);
    218     telnetd_task_id=0;
     213    telnetd_task_id = RTEMS_ID_NONE;
    219214    rtems_task_delete(RTEMS_SELF);
    220215  };
     
    222217    perror("telnetd:listen");
    223218          close(des_socket);
    224     telnetd_task_id=0;
     219    telnetd_task_id = RTEMS_ID_NONE;
    225220    rtems_task_delete(RTEMS_SELF);
    226221  };
     
    230225   */
    231226  do {
    232     if ( telnetd_remain_on_caller_stdio ) {
    233       char device_name[32];
    234       ttyname_r( 1, device_name, sizeof(device_name) );
    235       if ( !telnetd_askForPassword || (0 == check_passwd(arg->peername)) )
    236         telnetd_shell(device_name, telnetd_shell_arg);
     227    if (rtems_telnetd_config.keep_stdio) {
     228      bool start = true;
     229      char device_name [32];
     230
     231      ttyname_r( 1, device_name, sizeof( device_name));
     232      if (rtems_telnetd_config.login_check != NULL) {
     233        start = rtems_shell_login_prompt(
     234          stdin,
     235          stderr,
     236          device_name,
     237          rtems_telnetd_config.login_check
     238        );
     239      }
     240      if (start) {
     241        rtems_telnetd_config.command( device_name, arg->arg);
     242      } else {
     243        syslog(
     244          LOG_AUTHPRIV | LOG_WARNING,
     245          "telnetd: to many wrong passwords entered from %s",
     246          device_name
     247        );
     248      }
    237249    } else {
    238250      devname = grab_a_Connection(des_socket, &srv, peername, sizeof(peername));
    239251
    240252      if ( !devname ) {
    241         /* if something went wrong, sleep for some time */
    242         sleep(10);
    243         continue;
     253        /* if something went wrong, sleep for some time */
     254        sleep(10);
     255        continue;
    244256      }
    245257
     
    247259
    248260      arg->devname = devname;
    249       arg->arg = telnetd_shell_arg;
     261      arg->arg = rtems_telnetd_config.arg;
    250262      strncpy(arg->peername, peername, sizeof(arg->peername));
    251263
    252       if ( !telnetd_spawn_task( &devname[5], telnetd_task_priority,
    253                telnetd_stack_size, spawned_shell, arg) ) {
     264      telnetd_task_id = (rtems_id) telnetd_spawn_task(
     265        devname,
     266        rtems_telnetd_config.priority,
     267        rtems_telnetd_config.stack_size,
     268        spawned_shell,
     269        arg
     270      );
     271      if (telnetd_task_id == RTEMS_ID_NONE) {
    254272        FILE *dummy;
    255273
     
    274292  } while(1);
    275293
    276   /* TODO: how to free the connection semaphore? But then - 
     294  /* TODO: how to free the connection semaphore? But then -
    277295   *       stopping the daemon is probably only needed during
    278296   *       development/debugging.
     
    281299   */
    282300  close(des_socket);
    283   telnetd_task_id=0;
    284 }
    285 
    286 /***********************************************************/
    287 static int initialize_telnetd(void) {
    288  
    289   if (telnetd_task_id         ) return RTEMS_RESOURCE_IN_USE;
    290   if (telnetd_stack_size<=0   ) telnetd_stack_size   =32000;
    291 
    292   if ( !telnetd_spawn_task("TNTD", telnetd_task_priority,
    293           RTEMS_MINIMUM_STACK_SIZE, rtems_task_telnetd, 0) ) {
    294     return -1;
    295   }
    296   return 0;
    297 }
    298 
    299 /***********************************************************/
    300 int rtems_telnetd_initialize(
    301   void               (*cmd)(char *, void *),
    302   void                *arg,
    303   bool                 remainOnCallerSTDIO,
    304   size_t               stack,
    305   rtems_task_priority  priority,
    306   bool                 askForPassword
    307 )
    308 {
    309   rtems_status_code sc;
    310 
    311 #if 0
    312   printf("This is rtems-telnetd (modified by Till Straumann)\n");
    313   printf("$Id$\n");
    314   printf("Release $Name$\n");
    315 #endif
    316 
    317   if ( !telnetd_shell && !cmd ) {
    318     fprintf(stderr,"startTelnetd(): setup error - NO SHELL; bailing out\n");
    319     return 1;
    320   }
    321 
    322   if (telnetd_task_id) {
    323     fprintf(stderr,"ERROR:telnetd already started\n");
    324     return 1;
    325   };
     301  telnetd_task_id = RTEMS_ID_NONE;
     302}
     303
     304rtems_status_code rtems_telnetd_initialize( void)
     305{
     306  rtems_status_code sc = RTEMS_SUCCESSFUL;
     307
     308  if (telnetd_task_id != RTEMS_ID_NONE) {
     309    fprintf(stderr, "telnetd already started\n");
     310    return RTEMS_RESOURCE_IN_USE;
     311  }
     312
     313  if (rtems_telnetd_config.command == NULL) {
     314    fprintf(stderr, "telnetd setup with invalid command\n");
     315    return RTEMS_IO_ERROR;
     316  }
    326317
    327318  if ( !telnet_pty_initialize() ) {
    328     fprintf(stderr,"PTY driver probably not properly registered\n");
    329     return 1;
    330   }
    331 
    332   telnetd_askForPassword = askForPassword;
    333 
    334   if (cmd)
    335     telnetd_shell = cmd;
    336   telnetd_shell_arg     = arg;
    337   telnetd_stack_size    = stack;
    338   if ( !priority ) {
    339     priority = rtems_bsdnet_config.network_task_priority;
    340   }
    341   if ( priority < 2 )
    342     priority = 100;
    343   telnetd_task_priority          = priority;
    344   telnetd_remain_on_caller_stdio = remainOnCallerSTDIO;
    345 
    346   sc = initialize_telnetd();
    347   if (sc != RTEMS_SUCCESSFUL) return sc;
    348 
    349   if ( !telnetd_remain_on_caller_stdio )
    350     fprintf(stderr, "rtems_telnetd() started with stacksize=%u,priority=%d\n",
    351       (unsigned)telnetd_stack_size,(int)telnetd_task_priority);
    352   return 0;
     319    fprintf(stderr, "telnetd cannot initialize PTY driver\n");
     320    return RTEMS_IO_ERROR;
     321  }
     322
     323  /* Check priority */
     324  if (rtems_telnetd_config.priority <= 0) {
     325    rtems_telnetd_config.priority = rtems_bsdnet_config.network_task_priority;
     326  }
     327  if (rtems_telnetd_config.priority < 2) {
     328    rtems_telnetd_config.priority = 100;
     329  }
     330
     331  /* Check stack size */
     332  if (rtems_telnetd_config.stack_size <= 0) {
     333    rtems_telnetd_config.stack_size = 32 * 1024;
     334  }
     335
     336  /* Spawn task */
     337  telnetd_task_id = (rtems_id) telnetd_spawn_task(
     338    "TNTD",
     339    rtems_telnetd_config.priority,
     340    RTEMS_MINIMUM_STACK_SIZE,
     341    rtems_task_telnetd,
     342    0
     343  );
     344  if (telnetd_task_id == RTEMS_ID_NONE) {
     345    return RTEMS_IO_ERROR;
     346  }
     347
     348  /* Print status */
     349  if (!rtems_telnetd_config.keep_stdio) {
     350    fprintf(
     351      stderr,
     352      "telnetd started with stacksize = %u and priority = %d\n",
     353      (unsigned) rtems_telnetd_config.stack_size,
     354      (unsigned) rtems_telnetd_config.priority
     355    );
     356  }
     357
     358  return RTEMS_SUCCESSFUL;
    353359}
    354360
     
    362368  int                  i=0;
    363369  struct shell_args  *arg = targ;
     370  bool login_failed = false;
     371  bool start = true;
    364372
    365373  sc=rtems_libio_set_private_env();
     
    398406
    399407  /* call their routine */
    400   if ( !telnetd_askForPassword || (0 == check_passwd(arg->peername)) )
    401     telnetd_shell(arg->devname, arg->arg);
     408  if (rtems_telnetd_config.login_check != NULL) {
     409    start = rtems_shell_login_prompt(
     410      stdin,
     411      stderr,
     412      arg->devname,
     413      rtems_telnetd_config.login_check
     414    );
     415    login_failed = !start;
     416  }
     417  if (start) {
     418    rtems_telnetd_config.command( arg->devname, arg->arg);
     419  }
    402420
    403421  stdin  = ostd[0];
    404422  stdout = ostd[1];
    405423  stderr = ostd[2];
     424
     425  if (login_failed) {
     426    syslog(
     427      LOG_AUTHPRIV | LOG_WARNING,
     428      "telnetd: to many wrong passwords entered from %s",
     429      arg->peername
     430    );
     431  }
    406432
    407433cleanup:
     
    434460{
    435461  rtems_status_code        sc;
    436   rtems_id                 task_id;
     462  rtems_id                 task_id = RTEMS_ID_NONE;
    437463  char                     nm[4] = {'X','X','X','X' };
    438464  struct wrap_delete_args *pwa = malloc(sizeof(*pwa));
     
    442468  if ( !pwa ) {
    443469    perror("Telnetd: no memory\n");
    444     return 0;
     470    return (void *) RTEMS_ID_NONE;
    445471  }
    446472
     
    461487        free(pwa);
    462488        rtems_error(sc,"Telnetd: spawning task failed");
    463         return 0;
    464   }
    465   return (void*)task_id;
     489        return (void *) RTEMS_ID_NONE;
     490  }
     491  return (void *) task_id;
    466492}
    467493
  • cpukit/telnetd/telnetd.h

    r8916bdc7 r8a775c27  
    44 *  Reworked by Till Straumann and .h overhauled by Joel Sherrill.
    55 *
    6  *  This program is distributed in the hope that it will be useful,
    7  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    8  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
     6 * Copyright (c) 2009
     7 * embedded brains GmbH
     8 * Obere Lagerstr. 30
     9 * D-82178 Puchheim
     10 * Germany
     11 * <rtems@embedded-brains.de>
    912 *
    10  *  $Id$
     13 * Modified by Sebastian Huber <sebastian.huber@embedded-brains.de>.
     14 *
     15 * The license and distribution terms for this file may be
     16 * found in the file LICENSE in this distribution or at
     17 * http://www.rtems.com/license/LICENSE.
     18 *
     19 * $Id$
    1120 */
    1221
     
    1423#define _RTEMS_TELNETD_H
    1524
     25#include <rtems.h>
     26#include <rtems/login.h>
     27
    1628#ifdef __cplusplus
    1729extern "C" {
    18 #endif 
     30#endif
     31
     32bool rtems_telnetd_login_check(
     33  const char *user,
     34  const char *passphrase
     35);
    1936
    2037/**
    21  *  This method initializes the telnetd subsystem.
     38 * @brief Telnet command type.
     39 */
     40typedef void (*rtems_telnetd_command)(
     41  char * /* device name */,
     42  void * /* arg */
     43);
     44
     45/**
     46 * @brief Telnet configuration structure.
     47 */
     48typedef struct {
     49  /**
     50   * @brief Function invoked for each Telnet connection.
     51   *
     52   * The first parameter contains the device name.  The second parameter
     53   * contains the argument pointer of this configuration table.
     54   */
     55  rtems_telnetd_command command;
     56
     57  /**
     58   * @brief Argument for command function.
     59   */
     60  void *arg;
     61
     62  /**
     63   * @brief Task priority.
     64   *
     65   * If this parameter is equal to zero, then the priority of network task is
     66   * used or 100 if this priority is less than two.
     67   */
     68  rtems_task_priority priority;
     69
     70  /**
     71   * @brief Task stack size.
     72   */
     73  size_t stack_size;
     74
     75  /**
     76   * @brief Login check function.
     77   *
     78   * Method used for login checks.  Use @c NULL to disable a login check.
     79   */
     80  rtems_login_check login_check;
     81
     82  /**
     83   * @brief Keep standard IO of the caller.
     84   *
     85   * Telnet takes over the standard input, output and error associated with
     86   * task, if this parameter is set to @c true.  In this case, it will @b not
     87   * listen on any sockets.  When this parameter is @c false, Telnet will
     88   * create other tasks for the shell which listen on sockets.
     89   */
     90  bool keep_stdio;
     91} rtems_telnetd_config_table;
     92
     93/**
     94 * @brief Telnet configuration.
    2295 *
    23  *  @param[in] cmd is the function which is the "shell" telnetd invokes
    24  *  @param[in] arg is the context pointer to cmd
    25  *  @param[in] remainOnCallerSTDIO is set to TRUE if telnetd takes over the
    26  *    standard in, out and error associated with task.  In this case,
    27  *    it will be NOT be listening on any sockets.  When this parameters
    28  *    is FALSE the telnetd will create other tasks for the shell
    29  *    which listen on sockets.
    30  *  @param[in] stack is stack size of spawned task.
    31  *  @param[in] priority is the initial priority of spawned task(s).  If
    32  *    this parameter is less than 2, then the default priority of 100 is used.
    33  *  @param[in] askForPassword is set to TRUE if telnetd is to ask for a
    34  *    password. This is set to FALSE to invoke "cmd" with no password check.
    35  *    This may be OK if "cmd" includes its own check and indeed the RTEMS Shell
    36  *    uses a login with a user name and password so this is the usual case.
     96 * The application must provide this configuration table.  It is used by
     97 * rtems_telnetd_initialize() to configure the Telnet subsystem.  Do not modify
     98 * the entries after the intialization since it is used internally.
    3799 */
    38 int rtems_telnetd_initialize(
    39   void               (*cmd)(char *, void *),
    40   void                *arg,
    41   bool                 remainOnCallerSTDIO,
    42   size_t               stack,
    43   rtems_task_priority  priority,
    44   bool                 askForPassword
    45 );
     100extern rtems_telnetd_config_table rtems_telnetd_config;
     101
     102/**
     103 * @brief Initializes the Telnet subsystem.
     104 *
     105 * Uses the application provided @ref rtems_telnetd_config configuration table.
     106 */
     107rtems_status_code rtems_telnetd_initialize( void);
    46108
    47109#ifdef __cplusplus
    48110}
    49 #endif 
     111#endif
    50112
    51113#endif
Note: See TracChangeset for help on using the changeset viewer.