Index: cpukit/telnetd/check_passwd.c
===================================================================
--- cpukit/telnetd/check_passwd.c	(revision 8ad6681b6bb601c670726ca36c924f5852d01efd)
+++ cpukit/telnetd/check_passwd.c	(revision 8ad6681b6bb601c670726ca36c924f5852d01efd)
@@ -0,0 +1,200 @@
+/* $Id$ */
+
+/* Read a password, encrypt it and compare to the encrypted 
+ * password in the TELNETD_PASSWD environment variable.
+ * No password is required if TELNETD_PASSWD is unset
+ */
+
+/* 
+ * Authorship
+ * ----------
+ * This software was created by
+ *     Till Straumann <strauman@slac.stanford.edu>, 2003-2007
+ * 	   Stanford Linear Accelerator Center, Stanford University.
+ * 
+ * Acknowledgement of sponsorship
+ * ------------------------------
+ * This software was produced by
+ *     the Stanford Linear Accelerator Center, Stanford University,
+ * 	   under Contract DE-AC03-76SFO0515 with the Department of Energy.
+ * 
+ * Government disclaimer of liability
+ * ----------------------------------
+ * Neither the United States nor the United States Department of Energy,
+ * nor any of their employees, makes any warranty, express or implied, or
+ * assumes any legal liability or responsibility for the accuracy,
+ * completeness, or usefulness of any data, apparatus, product, or process
+ * disclosed, or represents that its use would not infringe privately owned
+ * rights.
+ * 
+ * Stanford disclaimer of liability
+ * --------------------------------
+ * Stanford University makes no representations or warranties, express or
+ * implied, nor assumes any liability for the use of this software.
+ * 
+ * Stanford disclaimer of copyright
+ * --------------------------------
+ * Stanford University, owner of the copyright, hereby disclaims its
+ * copyright and all other rights in this software.  Hence, anyone may
+ * freely use it for any purpose without restriction.  
+ * 
+ * Maintenance of notices
+ * ----------------------
+ * In the interest of clarity regarding the origin and status of this
+ * SLAC software, this and all the preceding Stanford University notices
+ * are to remain affixed to any copy or derivative of this software made
+ * or distributed by the recipient and are to be affixed to any copy of
+ * software made or distributed by the recipient that contains a copy or
+ * derivative of this software.
+ * 
+ * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
+ */ 
+
+#if !defined(INSIDE_TELNETD) && !defined(__rtems__)
+#include <crypt.h>
+#endif
+#include <termios.h>
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+
+#include "passwd.h"
+
+/* rtems has global filedescriptors but per-thread stdio streams... */
+#define STDI_FD fileno(stdin)
+#define MAXPASSRETRY	3
+
+extern char *__des_crypt_r(char *, char*, char*, int);
+
+#if !defined(INSIDE_TELNETD)
+#define sockpeername(s,b,sz) (-1)
+#endif
+
+#if defined(INSIDE_TELNETD)
+static
+#endif
+int check_passwd(char *peername)
+{
+char			*pw;
+int				rval = -1, tmp, retries;
+struct termios	t,told;
+int				restore_flags = 0;
+char			buf[30], cryptbuf[21];
+char			salt[3];
+
+  if ( !(pw=getenv("TELNETD_PASSWD")) || 0 == strlen(pw) )
+#ifdef TELNETD_DEFAULT_PASSWD
+    pw = TELNETD_DEFAULT_PASSWD;
+#else
+    return 0;
+#endif
+
+  if ( tcgetattr(STDI_FD, &t) ) {
+    perror("check_passwd(): tcgetattr");
+    goto done;	
+  }
+  told = t;
+  t.c_lflag &= ~ECHO;
+  t.c_lflag &= ~ICANON;
+  t.c_cc[VTIME] = 255;
+  t.c_cc[VMIN]  = 0;
+
+  strncpy(salt,pw,2);
+  salt[2]=0;
+
+  if ( tcsetattr(STDI_FD, TCSANOW, &t) ) {
+    perror("check_passwd(): tcsetattr");
+    goto done;	
+  }
+  restore_flags = 1;
+
+  /* Here we ask for the password... */
+  for ( retries = MAXPASSRETRY; retries > 0; retries-- ) {
+    fflush(stdin);
+    fprintf(stderr,"Password:");
+    fflush(stderr);
+    if ( 0 == fgets(buf,sizeof(buf),stdin) ) {
+      /* Here comes an ugly hack:
+       * The termios driver's 'read()' handler
+       * returns 0 to the c library's fgets if
+       * it times out. 'fgets' interprets this
+       * (correctly) as EOF, a condition we want
+       * to undo since it's not really true since
+       * we really have a read error (termios bug??)
+       *
+       * As a workaround we push something back and
+       * read it again. This should simply reset the
+       * EOF condition.
+       */
+      if (ungetc('?',stdin) >= 0)
+        fgetc(stdin);
+      goto done;
+    }
+    fputc('\n',stderr);
+    tmp = strlen(buf);
+    while ( tmp > 0 && ('\n' == buf[tmp-1] || '\r' == buf[tmp-1]) ) {
+      buf[--tmp]=0;
+    }
+    if ( !strcmp(__des_crypt_r(buf, salt, cryptbuf, sizeof(cryptbuf)), pw) ) {
+      rval = 0;
+      break;
+    }
+    fprintf(stderr,"Incorrect Password.\n");
+    sleep(2);
+  }
+
+  if ( 0 == retries ) {
+    syslog( LOG_AUTHPRIV | LOG_WARNING,
+      "telnetd: %i wrong passwords entered from %s",
+      MAXPASSRETRY,
+      peername ? peername : "<UNKNOWN>");
+  }
+
+done:
+  /* what to do if restoring the flags fails?? */
+  if (restore_flags)
+    tcsetattr(STDI_FD, TCSANOW, &told);
+  
+  if (rval) {
+    sleep(2);
+  }
+  return rval;
+}
+
+#if !defined(INSIDE_TELNETD) && !defined(__rtems__)
+int
+main(int argc, char **argv)
+{
+char *str, *enc=0;
+int   ch;
+
+while ( (ch=getopt(argc, argv, "g:")) > 0 ) {
+  switch (ch) {
+    default:
+      fprintf(stderr,"Unknown option\n");
+    return(1);
+
+    case 'g':
+      printf("Generated encrypted password: '%s'\n", (enc=crypt(optarg,"td")));
+    break;
+      
+  }
+}
+if (argc>optind && !enc) {
+  enc=argv[optind];
+}
+if (enc) {
+  str = malloc(strlen(enc) + 30);
+  sprintf(str,"TELNETD_PASSWD=%s",enc);
+  putenv(str);
+}
+if (check_passwd(-1)) {
+  fprintf(stderr,"check_passwd() failed\n");
+}
+return 0;
+}
+
+#endif
