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