summaryrefslogtreecommitdiffstats
path: root/cpukit/telnetd/check_passwd.c
diff options
context:
space:
mode:
Diffstat (limited to 'cpukit/telnetd/check_passwd.c')
-rw-r--r--cpukit/telnetd/check_passwd.c200
1 files changed, 200 insertions, 0 deletions
diff --git a/cpukit/telnetd/check_passwd.c b/cpukit/telnetd/check_passwd.c
new file mode 100644
index 0000000000..e1df00d2d9
--- /dev/null
+++ b/cpukit/telnetd/check_passwd.c
@@ -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