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