123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207 |
- /***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at https://curl.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * SPDX-License-Identifier: curl
- *
- ***************************************************************************/
- #include "tool_setup.h"
- #if defined(__AMIGA__) && !defined(__amigaos4__)
- # undef HAVE_TERMIOS_H
- #endif
- #ifndef HAVE_GETPASS_R
- /* this file is only for systems without getpass_r() */
- #ifdef HAVE_FCNTL_H
- # include <fcntl.h>
- #endif
- #ifdef HAVE_TERMIOS_H
- # include <termios.h>
- #elif defined(HAVE_TERMIO_H)
- # include <termio.h>
- #endif
- #ifdef __VMS
- # include descrip
- # include starlet
- # include iodef
- #endif
- #ifdef _WIN32
- # include <conio.h>
- #endif
- #ifdef HAVE_UNISTD_H
- #include <unistd.h>
- #endif
- #include "tool_getpass.h"
- #include "memdebug.h" /* keep this as LAST include */
- #ifdef __VMS
- /* VMS implementation */
- char *getpass_r(const char *prompt, char *buffer, size_t buflen)
- {
- long sts;
- short chan;
- /* MSK, 23-JAN-2004, iosbdef.h was not in VAX V7.2 or CC 6.4 */
- /* distribution so I created this. May revert back later to */
- /* struct _iosb iosb; */
- struct _iosb
- {
- short int iosb$w_status; /* status */
- short int iosb$w_bcnt; /* byte count */
- int unused; /* unused */
- } iosb;
- $DESCRIPTOR(ttdesc, "TT");
- buffer[0] = '\0';
- sts = sys$assign(&ttdesc, &chan, 0, 0);
- if(sts & 1) {
- sts = sys$qiow(0, chan,
- IO$_READPROMPT | IO$M_NOECHO,
- &iosb, 0, 0, buffer, buflen, 0, 0,
- prompt, strlen(prompt));
- if((sts & 1) && (iosb.iosb$w_status & 1))
- buffer[iosb.iosb$w_bcnt] = '\0';
- sys$dassgn(chan);
- }
- return buffer; /* we always return success */
- }
- #define DONE
- #endif /* __VMS */
- #if defined(_WIN32)
- char *getpass_r(const char *prompt, char *buffer, size_t buflen)
- {
- size_t i;
- fputs(prompt, tool_stderr);
- for(i = 0; i < buflen; i++) {
- buffer[i] = (char)_getch();
- if(buffer[i] == '\r' || buffer[i] == '\n') {
- buffer[i] = '\0';
- break;
- }
- else
- if(buffer[i] == '\b')
- /* remove this letter and if this is not the first key, remove the
- previous one as well */
- i = i - (i >= 1 ? 2 : 1);
- }
- /* since echo is disabled, print a newline */
- fputs("\n", tool_stderr);
- /* if user did not hit ENTER, terminate buffer */
- if(i == buflen)
- buffer[buflen-1] = '\0';
- return buffer; /* we always return success */
- }
- #define DONE
- #endif /* _WIN32 */
- #ifndef DONE /* not previously provided */
- #ifdef HAVE_TERMIOS_H
- # define struct_term struct termios
- #elif defined(HAVE_TERMIO_H)
- # define struct_term struct termio
- #else
- # undef struct_term
- #endif
- static bool ttyecho(bool enable, int fd)
- {
- #ifdef struct_term
- static struct_term withecho;
- static struct_term noecho;
- #endif
- if(!enable) {
- /* disable echo by extracting the current 'withecho' mode and remove the
- ECHO bit and set back the struct */
- #ifdef HAVE_TERMIOS_H
- tcgetattr(fd, &withecho);
- noecho = withecho;
- noecho.c_lflag &= ~(tcflag_t)ECHO;
- tcsetattr(fd, TCSANOW, &noecho);
- #elif defined(HAVE_TERMIO_H)
- ioctl(fd, TCGETA, &withecho);
- noecho = withecho;
- noecho.c_lflag &= ~(tcflag_t)ECHO;
- ioctl(fd, TCSETA, &noecho);
- #else
- /* neither HAVE_TERMIO_H nor HAVE_TERMIOS_H, we cannot disable echo! */
- (void)fd;
- return FALSE; /* not disabled */
- #endif
- return TRUE; /* disabled */
- }
- /* re-enable echo, assumes we disabled it before (and set the structs we
- now use to reset the terminal status) */
- #ifdef HAVE_TERMIOS_H
- tcsetattr(fd, TCSAFLUSH, &withecho);
- #elif defined(HAVE_TERMIO_H)
- ioctl(fd, TCSETA, &withecho);
- #else
- return FALSE; /* not enabled */
- #endif
- return TRUE; /* enabled */
- }
- char *getpass_r(const char *prompt, /* prompt to display */
- char *password, /* buffer to store password in */
- size_t buflen) /* size of buffer to store password in */
- {
- ssize_t nread;
- bool disabled;
- int fd = open("/dev/tty", O_RDONLY);
- if(-1 == fd)
- fd = STDIN_FILENO; /* use stdin if the tty could not be used */
- disabled = ttyecho(FALSE, fd); /* disable terminal echo */
- fputs(prompt, tool_stderr);
- nread = read(fd, password, buflen);
- if(nread > 0)
- password[--nread] = '\0'; /* null-terminate where enter is stored */
- else
- password[0] = '\0'; /* got nothing */
- if(disabled) {
- /* if echo actually was disabled, add a newline */
- fputs("\n", tool_stderr);
- (void)ttyecho(TRUE, fd); /* enable echo */
- }
- if(STDIN_FILENO != fd)
- close(fd);
- return password; /* return pointer to buffer */
- }
- #endif /* DONE */
- #endif /* HAVE_GETPASS_R */
|