import cyrus-sasl-2.1.23
[cyrus-sasl.git] / mac / libdes / src / read_pwd.c
1 /* crypto/des/read_pwd.c */\r/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)\r * All rights reserved.\r *\r * This package is an SSL implementation written\r * by Eric Young (eay@mincom.oz.au).\r * The implementation was written so as to conform with Netscapes SSL.\r * \r * This library is free for commercial and non-commercial use as long as\r * the following conditions are aheared to.  The following conditions\r * apply to all code found in this distribution, be it the RC4, RSA,\r * lhash, DES, etc., code; not just the SSL code.  The SSL documentation\r * included with this distribution is covered by the same copyright terms\r * except that the holder is Tim Hudson (tjh@mincom.oz.au).\r * \r * Copyright remains Eric Young's, and as such any Copyright notices in\r * the code are not to be removed.\r * If this package is used in a product, Eric Young should be given attribution\r * as the author of the parts of the library used.\r * This can be in the form of a textual message at program startup or\r * in documentation (online or textual) provided with the package.\r * \r * Redistribution and use in source and binary forms, with or without\r * modification, are permitted provided that the following conditions\r * are met:\r * 1. Redistributions of source code must retain the copyright\r *    notice, this list of conditions and the following disclaimer.\r * 2. Redistributions in binary form must reproduce the above copyright\r *    notice, this list of conditions and the following disclaimer in the\r *    documentation and/or other materials provided with the distribution.\r * 3. All advertising materials mentioning features or use of this software\r *    must display the following acknowledgement:\r *    "This product includes cryptographic software written by\r *     Eric Young (eay@mincom.oz.au)"\r *    The word 'cryptographic' can be left out if the rouines from the library\r *    being used are not cryptographic related :-).\r * 4. If you include any Windows specific code (or a derivative thereof) from \r *    the apps directory (application code) you must include an acknowledgement:\r *    "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"\r * \r * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND\r * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\r * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r * SUCH DAMAGE.\r * \r * The licence and distribution terms for any publically available version or\r * derivative of this code cannot be changed.  i.e. this code cannot simply be\r * copied and put under another distribution licence\r * [including the GNU Public Licence.]\r */\r\r#ifdef WIN16TTY\r#undef WIN16\r#undef _WINDOWS\r#include <graph.h>\r#endif\r\r/* 06-Apr-92 Luke Brennan    Support for VMS */\r#include "des_locl.h"\r#include <signal.h>\r#include <string.h>\r#include <setjmp.h>\r#include <errno.h>\r\r/* There are 5 types of terminal interface supported,\r * TERMIO, TERMIOS, VMS, MSDOS and SGTTY\r */\r\r#if defined(__sgi) && !defined(TERMIOS)\r#define TERMIOS\r#undef TERMIO\r#undef SGTTY\r#endif\r\r#if defined(linux) && !defined(TERMIO)\r#undef TERMIOS\r#define TERMIO\r#undef SGTTY\r#endif\r\r#ifdef _LIBC\r#define TERMIO\r#endif\r\r#if !defined(TERMIO) && !defined(TERMIOS) && !defined(VMS) && !defined(MSDOS)\r#define SGTTY\r#endif\r\r#ifdef TERMIOS\r#include <termios.h>\r#define TTY_STRUCT          struct termios\r#define TTY_FLAGS                c_lflag\r#define TTY_get(tty,data)       tcgetattr(tty,data)\r#define TTY_set(tty,data)   tcsetattr(tty,TCSANOW,data)\r#endif\r\r#ifdef TERMIO\r#include <termio.h>\r#define TTY_STRUCT                struct termio\r#define TTY_FLAGS         c_lflag\r#define TTY_get(tty,data)       ioctl(tty,TCGETA,data)\r#define TTY_set(tty,data)        ioctl(tty,TCSETA,data)\r#endif\r\r#ifdef SGTTY\r#include <sgtty.h>\r#define TTY_STRUCT               struct sgttyb\r#define TTY_FLAGS         sg_flags\r#define TTY_get(tty,data)      ioctl(tty,TIOCGETP,data)\r#define TTY_set(tty,data)      ioctl(tty,TIOCSETP,data)\r#endif\r\r#if !defined(_LIBC) && !defined(MSDOS) && !defined(VMS)\r#include <sys/ioctl.h>\r#endif\r\r#ifdef MSDOS\r#include <conio.h>\r#define fgets(a,b,c) noecho_fgets(a,b,c)\r#endif\r\r#ifdef VMS\r#include <ssdef.h>\r#include <iodef.h>\r#include <ttdef.h>\r#include <descrip.h>\rstruct IOSB {\r        short iosb$w_value;\r    short iosb$w_count;\r    long  iosb$l_info;\r     };\r#endif\r\r#ifndef NX509_SIG\r#define NX509_SIG 32\r#endif\r\r#ifndef NOPROTO\rstatic void read_till_nl(FILE *);\rstatic int read_pw(char *buf, char *buff, int size, char *prompt, int verify);\rstatic void recsig(int);\rstatic void pushsig(void);\rstatic void popsig(void);\r#if defined(MSDOS) && !defined(WIN16)\rstatic int noecho_fgets(char *buf, int size, FILE *tty);\r#endif\r#else\rstatic void read_till_nl();\rstatic int read_pw();\rstatic void recsig();\rstatic void pushsig();\rstatic void popsig();\r#if defined(MSDOS) && !defined(WIN16)\rstatic int noecho_fgets();\r#endif\r#endif\r\r#ifndef NOPROTO\rstatic void (*savsig[NX509_SIG])(int );\r#else\rstatic void (*savsig[NX509_SIG])();\r#endif\rstatic jmp_buf save;\r\rint des_read_password(key, prompt, verify)\rdes_cblock (*key);\rchar *prompt;\rint verify;\r       {\r      int ok;\r        char buf[BUFSIZ],buff[BUFSIZ];\r\r        if ((ok=read_pw(buf,buff,BUFSIZ,prompt,verify)) == 0)\r          des_string_to_key(buf,key);\r    memset(buf,0,BUFSIZ);\r  memset(buff,0,BUFSIZ);\r return(ok);\r    }\r\rint des_read_2passwords(key1, key2, prompt, verify)\rdes_cblock (*key1);\rdes_cblock (*key2);\rchar *prompt;\rint verify;\r       {\r      int ok;\r        char buf[BUFSIZ],buff[BUFSIZ];\r\r        if ((ok=read_pw(buf,buff,BUFSIZ,prompt,verify)) == 0)\r          des_string_to_2keys(buf,key1,key2);\r    memset(buf,0,BUFSIZ);\r  memset(buff,0,BUFSIZ);\r return(ok);\r    }\r\rint des_read_pw_string(buf, length, prompt, verify)\rchar *buf;\rint length;\rchar *prompt;\rint verify;\r        {\r      char buff[BUFSIZ];\r     int ret;\r\r      ret=read_pw(buf,buff,(length>BUFSIZ)?BUFSIZ:length,prompt,verify);\r     memset(buff,0,BUFSIZ);\r return(ret);\r   }\r\r#ifndef WIN16\r\rstatic void read_till_nl(in)\rFILE *in;\r       {\r#define SIZE 4\r       char buf[SIZE+1];\r\r     do      {\r              fgets(buf,SIZE,in);\r            } while (strchr(buf,'\n') == NULL);\r    }\r\r\r/* return 0 if ok, 1 (or -1) otherwise */\rstatic int read_pw(buf, buff, size, prompt, verify)\rchar *buf;\rchar *buff;\rint size;\rchar *prompt;\rint verify;\r   {\r#ifdef VMS\r   struct IOSB iosb;\r      $DESCRIPTOR(terminal,"TT");\r    long tty_orig[3], tty_new[3];\r  long status;\r   unsigned short channel = 0;\r#else\r#ifndef MSDOS\r        TTY_STRUCT tty_orig,tty_new;\r#endif\r#endif\r     int number=5;\r  int ok=0;\r      int ps=0;\r      int is_a_tty=1;\r\r       FILE *tty=NULL;\r        char *p;\r\r#ifdef __CYGWIN32__\r  tty = stdin;\r#elif !defined(MSDOS)\r     if ((tty=fopen("/dev/tty","r")) == NULL)\r               tty=stdin;\r#else /* MSDOS */\r   if ((tty=fopen("con","r")) == NULL)\r            tty=stdin;\r#endif /* MSDOS */\r\r#if defined(TTY_get) && !defined(VMS)\r   if (TTY_get(fileno(tty),&tty_orig) == -1)\r              {\r#ifdef ENOTTY\r                if (errno == ENOTTY)\r                   is_a_tty=0;\r            else\r#endif\r                    return(-1);\r            }\r      memcpy(&(tty_new),&(tty_orig),sizeof(tty_orig));\r#endif\r#ifdef VMS\r     status = SYS$ASSIGN(&terminal,&channel,0,0);\r   if (status != SS$_NORMAL)\r              return(-1);\r    status=SYS$QIOW(0,channel,IO$_SENSEMODE,&iosb,0,0,tty_orig,12,0,0,0,0);\r        if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL))\r               return(-1);\r#endif\r\r    if (setjmp(save))\r              {\r              ok=0;\r          goto error;\r            }\r      pushsig();\r     ps=1;\r\r#ifdef TTY_FLAGS\r        tty_new.TTY_FLAGS &= ~ECHO;\r#endif\r\r#if defined(TTY_set) && !defined(VMS)\r      if (is_a_tty && (TTY_set(fileno(tty),&tty_new) == -1))\r         return(-1);\r#endif\r#ifdef VMS\r  tty_new[0] = tty_orig[0];\r      tty_new[1] = tty_orig[1] | TT$M_NOECHO;\r        tty_new[2] = tty_orig[2];\r      status = SYS$QIOW(0,channel,IO$_SETMODE,&iosb,0,0,tty_new,12,0,0,0,0);\r if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL))\r               return(-1);\r#endif\r     ps=2;\r\r while ((!ok) && (number--))\r            {\r              fputs(prompt,stderr);\r          fflush(stderr);\r\r               buf[0]='\0';\r           fgets(buf,size,tty);\r           if (feof(tty)) goto error;\r             if (ferror(tty)) goto error;\r           if ((p=(char *)strchr(buf,'\n')) != NULL)\r                      *p='\0';\r               else    read_till_nl(tty);\r             if (verify)\r                    {\r                      fprintf(stderr,"\nVerifying password - %s",prompt);\r                    fflush(stderr);\r                        buff[0]='\0';\r                  fgets(buff,size,tty);\r                  if (feof(tty)) goto error;\r                     if ((p=(char *)strchr(buff,'\n')) != NULL)\r                             *p='\0';\r                       else    read_till_nl(tty);\r                             \r                       if (strcmp(buf,buff) != 0)\r                             {\r                              fprintf(stderr,"\nVerify failure");\r                            fflush(stderr);\r                                break;\r                         /* continue; */\r                                }\r                      }\r              ok=1;\r          }\r\rerror:\r      fprintf(stderr,"\n");\r#ifdef DEBUG\r     perror("fgets(tty)");\r#endif\r   /* What can we do if there is an error? */\r#if defined(TTY_set) && !defined(VMS) \r      if (ps >= 2) TTY_set(fileno(tty),&tty_orig);\r#endif\r#ifdef VMS\r if (ps >= 2)\r           status = SYS$QIOW(0,channel,IO$_SETMODE,&iosb,0,0\r                      ,tty_orig,12,0,0,0,0);\r#endif\r  \r       if (ps >= 1) popsig();\r if (stdin != tty) fclose(tty);\r#ifdef VMS\r      status = SYS$DASSGN(channel);\r#endif\r   return(!ok);\r   }\r\r#else /* WIN16 */\r\rstatic int read_pw(buf, buff, size, prompt, verify)\rchar *buf;\rchar *buff;\rint size;\rchar *prompt;\rint verify;\r   { \r     memset(buf,0,size);\r    memset(buff,0,size);\r   return(0);\r     }\r\r#endif\r\rstatic void pushsig()\r       {\r      int i;\r\r        for (i=1; i<NX509_SIG; i++)\r            savsig[i]=signal(i,recsig);\r\r#ifdef SIGWINCH\r   signal(SIGWINCH,SIG_DFL);\r#endif\r       }\r\rstatic void popsig()\r        {\r      int i;\r\r        for (i=1; i<NX509_SIG; i++)\r            signal(i,savsig[i]);\r   }\r\rstatic void recsig(i)\rint i;\r        {\r      longjmp(save,1);\r#ifdef LINT\r   i=i;\r#endif\r    }\r\r#if defined(MSDOS) && !defined(WIN16)\rstatic int noecho_fgets(buf,size,tty)\rchar *buf;\rint size;\rFILE *tty;\r {\r      int i;\r char *p;\r\r      p=buf;\r for (;;)\r               {\r              if (size == 0)\r                 {\r                      *p='\0';\r                       break;\r                 }\r              size--;\r#ifdef WIN16TTY\r                i=_inchar();\r#else\r             i=getch();\r#endif\r              if (i == '\r') i='\n';\r         *(p++)=i;\r              if (i == '\n')\r                 {\r                      *p='\0';\r                       break;\r                 }\r              }\r      return(strlen(buf));\r   }\r#endif\r