Annotation of embedaddon/curl/src/tool_getpass.c, revision 1.1.1.1

1.1       misho       1: /***************************************************************************
                      2:  *                                  _   _ ____  _
                      3:  *  Project                     ___| | | |  _ \| |
                      4:  *                             / __| | | | |_) | |
                      5:  *                            | (__| |_| |  _ <| |___
                      6:  *                             \___|\___/|_| \_\_____|
                      7:  *
                      8:  * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
                      9:  *
                     10:  * This software is licensed as described in the file COPYING, which
                     11:  * you should have received as part of this distribution. The terms
                     12:  * are also available at https://curl.haxx.se/docs/copyright.html.
                     13:  *
                     14:  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
                     15:  * copies of the Software, and permit persons to whom the Software is
                     16:  * furnished to do so, under the terms of the COPYING file.
                     17:  *
                     18:  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
                     19:  * KIND, either express or implied.
                     20:  *
                     21:  ***************************************************************************/
                     22: #include "tool_setup.h"
                     23: 
                     24: #if defined(__AMIGA__) && !defined(__amigaos4__)
                     25: #  undef HAVE_TERMIOS_H
                     26: #endif
                     27: 
                     28: #ifndef HAVE_GETPASS_R
                     29: /* this file is only for systems without getpass_r() */
                     30: 
                     31: #ifdef HAVE_FCNTL_H
                     32: #  include <fcntl.h>
                     33: #endif
                     34: 
                     35: #ifdef HAVE_TERMIOS_H
                     36: #  include <termios.h>
                     37: #elif defined(HAVE_TERMIO_H)
                     38: #  include <termio.h>
                     39: #endif
                     40: 
                     41: #ifdef __VMS
                     42: #  include descrip
                     43: #  include starlet
                     44: #  include iodef
                     45: #endif
                     46: 
                     47: #ifdef WIN32
                     48: #  include <conio.h>
                     49: #endif
                     50: 
                     51: #ifdef NETWARE
                     52: #  ifdef __NOVELL_LIBC__
                     53: #    include <screen.h>
                     54: #  else
                     55: #    include <nwconio.h>
                     56: #  endif
                     57: #endif
                     58: 
                     59: #ifdef HAVE_UNISTD_H
                     60: #include <unistd.h>
                     61: #endif
                     62: #include "tool_getpass.h"
                     63: 
                     64: #include "memdebug.h" /* keep this as LAST include */
                     65: 
                     66: #ifdef __VMS
                     67: /* VMS implementation */
                     68: char *getpass_r(const char *prompt, char *buffer, size_t buflen)
                     69: {
                     70:   long sts;
                     71:   short chan;
                     72: 
                     73:   /* MSK, 23-JAN-2004, iosbdef.h wasn't in VAX V7.2 or CC 6.4  */
                     74:   /* distribution so I created this.  May revert back later to */
                     75:   /* struct _iosb iosb;                                        */
                     76:   struct _iosb
                     77:      {
                     78:      short int iosb$w_status; /* status     */
                     79:      short int iosb$w_bcnt;   /* byte count */
                     80:      int       unused;        /* unused     */
                     81:      } iosb;
                     82: 
                     83:   $DESCRIPTOR(ttdesc, "TT");
                     84: 
                     85:   buffer[0] = '\0';
                     86:   sts = sys$assign(&ttdesc, &chan, 0, 0);
                     87:   if(sts & 1) {
                     88:     sts = sys$qiow(0, chan,
                     89:                    IO$_READPROMPT | IO$M_NOECHO,
                     90:                    &iosb, 0, 0, buffer, buflen, 0, 0,
                     91:                    prompt, strlen(prompt));
                     92: 
                     93:     if((sts & 1) && (iosb.iosb$w_status & 1))
                     94:       buffer[iosb.iosb$w_bcnt] = '\0';
                     95: 
                     96:     sys$dassgn(chan);
                     97:   }
                     98:   return buffer; /* we always return success */
                     99: }
                    100: #define DONE
                    101: #endif /* __VMS */
                    102: 
                    103: #ifdef __SYMBIAN32__
                    104: #  define getch() getchar()
                    105: #endif
                    106: 
                    107: #if defined(WIN32) || defined(__SYMBIAN32__)
                    108: 
                    109: char *getpass_r(const char *prompt, char *buffer, size_t buflen)
                    110: {
                    111:   size_t i;
                    112:   fputs(prompt, stderr);
                    113: 
                    114:   for(i = 0; i < buflen; i++) {
                    115:     buffer[i] = (char)getch();
                    116:     if(buffer[i] == '\r' || buffer[i] == '\n') {
                    117:       buffer[i] = '\0';
                    118:       break;
                    119:     }
                    120:     else
                    121:       if(buffer[i] == '\b')
                    122:         /* remove this letter and if this is not the first key, remove the
                    123:            previous one as well */
                    124:         i = i - (i >= 1 ? 2 : 1);
                    125:   }
                    126: #ifndef __SYMBIAN32__
                    127:   /* since echo is disabled, print a newline */
                    128:   fputs("\n", stderr);
                    129: #endif
                    130:   /* if user didn't hit ENTER, terminate buffer */
                    131:   if(i == buflen)
                    132:     buffer[buflen-1] = '\0';
                    133: 
                    134:   return buffer; /* we always return success */
                    135: }
                    136: #define DONE
                    137: #endif /* WIN32 || __SYMBIAN32__ */
                    138: 
                    139: #ifdef NETWARE
                    140: /* NetWare implementation */
                    141: #ifdef __NOVELL_LIBC__
                    142: char *getpass_r(const char *prompt, char *buffer, size_t buflen)
                    143: {
                    144:   return getpassword(prompt, buffer, buflen);
                    145: }
                    146: #else
                    147: char *getpass_r(const char *prompt, char *buffer, size_t buflen)
                    148: {
                    149:   size_t i = 0;
                    150: 
                    151:   printf("%s", prompt);
                    152:   do {
                    153:     buffer[i++] = getch();
                    154:     if(buffer[i-1] == '\b') {
                    155:       /* remove this letter and if this is not the first key,
                    156:          remove the previous one as well */
                    157:       if(i > 1) {
                    158:         printf("\b \b");
                    159:         i = i - 2;
                    160:       }
                    161:       else {
                    162:         RingTheBell();
                    163:         i = i - 1;
                    164:       }
                    165:     }
                    166:     else if(buffer[i-1] != 13)
                    167:       putchar('*');
                    168: 
                    169:   } while((buffer[i-1] != 13) && (i < buflen));
                    170:   buffer[i-1] = '\0';
                    171:   printf("\r\n");
                    172:   return buffer;
                    173: }
                    174: #endif /* __NOVELL_LIBC__ */
                    175: #define DONE
                    176: #endif /* NETWARE */
                    177: 
                    178: #ifndef DONE /* not previously provided */
                    179: 
                    180: #ifdef HAVE_TERMIOS_H
                    181: #  define struct_term  struct termios
                    182: #elif defined(HAVE_TERMIO_H)
                    183: #  define struct_term  struct termio
                    184: #else
                    185: #  undef  struct_term
                    186: #endif
                    187: 
                    188: static bool ttyecho(bool enable, int fd)
                    189: {
                    190: #ifdef struct_term
                    191:   static struct_term withecho;
                    192:   static struct_term noecho;
                    193: #endif
                    194:   if(!enable) {
                    195:     /* disable echo by extracting the current 'withecho' mode and remove the
                    196:        ECHO bit and set back the struct */
                    197: #ifdef HAVE_TERMIOS_H
                    198:     tcgetattr(fd, &withecho);
                    199:     noecho = withecho;
                    200:     noecho.c_lflag &= ~ECHO;
                    201:     tcsetattr(fd, TCSANOW, &noecho);
                    202: #elif defined(HAVE_TERMIO_H)
                    203:     ioctl(fd, TCGETA, &withecho);
                    204:     noecho = withecho;
                    205:     noecho.c_lflag &= ~ECHO;
                    206:     ioctl(fd, TCSETA, &noecho);
                    207: #else
                    208:     /* neither HAVE_TERMIO_H nor HAVE_TERMIOS_H, we can't disable echo! */
                    209:     (void)fd;
                    210:     return FALSE; /* not disabled */
                    211: #endif
                    212:     return TRUE; /* disabled */
                    213:   }
                    214:   /* re-enable echo, assumes we disabled it before (and set the structs we
                    215:      now use to reset the terminal status) */
                    216: #ifdef HAVE_TERMIOS_H
                    217:   tcsetattr(fd, TCSAFLUSH, &withecho);
                    218: #elif defined(HAVE_TERMIO_H)
                    219:   ioctl(fd, TCSETA, &withecho);
                    220: #else
                    221:   return FALSE; /* not enabled */
                    222: #endif
                    223:   return TRUE; /* enabled */
                    224: }
                    225: 
                    226: char *getpass_r(const char *prompt, /* prompt to display */
                    227:                 char *password,     /* buffer to store password in */
                    228:                 size_t buflen)      /* size of buffer to store password in */
                    229: {
                    230:   ssize_t nread;
                    231:   bool disabled;
                    232:   int fd = open("/dev/tty", O_RDONLY);
                    233:   if(-1 == fd)
                    234:     fd = STDIN_FILENO; /* use stdin if the tty couldn't be used */
                    235: 
                    236:   disabled = ttyecho(FALSE, fd); /* disable terminal echo */
                    237: 
                    238:   fputs(prompt, stderr);
                    239:   nread = read(fd, password, buflen);
                    240:   if(nread > 0)
                    241:     password[--nread] = '\0'; /* zero terminate where enter is stored */
                    242:   else
                    243:     password[0] = '\0'; /* got nothing */
                    244: 
                    245:   if(disabled) {
                    246:     /* if echo actually was disabled, add a newline */
                    247:     fputs("\n", stderr);
                    248:     (void)ttyecho(TRUE, fd); /* enable echo */
                    249:   }
                    250: 
                    251:   if(STDIN_FILENO != fd)
                    252:     close(fd);
                    253: 
                    254:   return password; /* return pointer to buffer */
                    255: }
                    256: 
                    257: #endif /* DONE */
                    258: #endif /* HAVE_GETPASS_R */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>