NCBI C++ ToolKit
readpassphrase.c
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* OPENBSD ORIGINAL: lib/libc/gen/readpassphrase.c */
2 
3 /* $OpenBSD: readpassphrase.c,v 1.16 2003/06/17 21:56:23 millert Exp $ */
4 
5 /*
6  * Copyright (c) 2000-2002 Todd C. Miller <Todd.Miller@courtesan.com>
7  *
8  * Permission to use, copy, modify, and distribute this software for any
9  * purpose with or without fee is hereby granted, provided that the above
10  * copyright notice and this permission notice appear in all copies.
11  *
12  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19  *
20  * Sponsored in part by the Defense Advanced Research Projects
21  * Agency (DARPA) and Air Force Research Laboratory, Air Force
22  * Materiel Command, USAF, under agreement number F39502-99-1-0512.
23  */
24 
25 #if defined(LIBC_SCCS) && !defined(lint)
26 static const char rcsid[] = "$OpenBSD: readpassphrase.c,v 1.16 2003/06/17 21:56:23 millert Exp $";
27 #endif /* LIBC_SCCS and not lint */
28 
29 #include <config.h>
30 
31 #ifndef HAVE_READPASSPHRASE
32 
33 #include <stdarg.h>
34 #include <stdio.h>
35 
36 #ifdef HAVE_STDLIB_H
37 #include <stdlib.h>
38 #endif
39 
40 #ifdef HAVE_STRING_H
41 #include <string.h>
42 #endif
43 
44 #include <ctype.h>
45 
46 #ifdef HAVE_UNISTD_H
47 #include <unistd.h>
48 #endif
49 
50 #ifdef HAVE_SIGNAL_H
51 #include <signal.h>
52 #endif
53 
54 #ifdef HAVE_ERRNO_H
55 #include <errno.h>
56 #endif
57 
58 #ifdef HAVE_SYS_TYPES_H
59 #include <sys/types.h>
60 #endif
61 
62 #ifdef HAVE_SYS_STAT_H
63 #include <sys/stat.h>
64 #endif
65 
66 #include <fcntl.h>
67 
68 #ifdef HAVE_PATHS_H
69 #include <paths.h> /* For _PATH_XXX */
70 #endif
71 
73 
74 #if !defined(_WIN32) && !defined(_WIN64)
75 #include <termios.h>
76 
77 #ifndef _PATH_TTY
78 # define _PATH_TTY "/dev/tty"
79 #endif
80 
81 #ifdef TCSASOFT
82 # define _T_FLUSH (TCSAFLUSH|TCSASOFT)
83 #else
84 # define _T_FLUSH (TCSAFLUSH)
85 #endif
86 
87 /* SunOS 4.x which lacks _POSIX_VDISABLE, but has VDISABLE */
88 #if !defined(_POSIX_VDISABLE) && defined(VDISABLE)
89 # define _POSIX_VDISABLE VDISABLE
90 #endif
91 
92 static volatile sig_atomic_t signo;
93 
94 static void handler(int);
95 
96 char *
97 tds_readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags)
98 {
99  ssize_t nr;
100  int input, output, save_errno;
101  char ch, *p, *end;
102  struct termios term, oterm;
103  struct sigaction sa, savealrm, saveint, savehup, savequit, saveterm;
104  struct sigaction savetstp, savettin, savettou, savepipe;
105 
106  /* I suppose we could alloc on demand in this case (XXX). */
107  if (bufsiz == 0) {
108  errno = EINVAL;
109  return(NULL);
110  }
111 
112 restart:
113  signo = 0;
114  /*
115  * Read and write to /dev/tty if available. If not, read from
116  * stdin and write to stderr unless a tty is required.
117  */
118  if ((flags & RPP_STDIN) ||
119  (input = output = open(_PATH_TTY, O_RDWR)) == -1) {
120  if (flags & RPP_REQUIRE_TTY) {
121  errno = ENOTTY;
122  return(NULL);
123  }
125  output = STDERR_FILENO;
126  }
127 
128  /*
129  * Catch signals that would otherwise cause the user to end
130  * up with echo turned off in the shell. Don't worry about
131  * things like SIGXCPU and SIGVTALRM for now.
132  */
133  sigemptyset(&sa.sa_mask);
134  sa.sa_flags = 0; /* don't restart system calls */
135  sa.sa_handler = handler;
136  (void)sigaction(SIGALRM, &sa, &savealrm);
137  (void)sigaction(SIGHUP, &sa, &savehup);
138  (void)sigaction(SIGINT, &sa, &saveint);
139  (void)sigaction(SIGPIPE, &sa, &savepipe);
140  (void)sigaction(SIGQUIT, &sa, &savequit);
141  (void)sigaction(SIGTERM, &sa, &saveterm);
142  (void)sigaction(SIGTSTP, &sa, &savetstp);
143  (void)sigaction(SIGTTIN, &sa, &savettin);
144  (void)sigaction(SIGTTOU, &sa, &savettou);
145 
146  /* Turn off echo if possible. */
147  if (input != STDIN_FILENO && tcgetattr(input, &oterm) == 0) {
148  memcpy(&term, &oterm, sizeof(term));
149  if (!(flags & RPP_ECHO_ON))
150  term.c_lflag &= ~(ECHO | ECHONL);
151 #ifdef VSTATUS
152  if (term.c_cc[VSTATUS] != _POSIX_VDISABLE)
153  term.c_cc[VSTATUS] = _POSIX_VDISABLE;
154 #endif
155  (void)tcsetattr(input, _T_FLUSH, &term);
156  } else {
157  memset(&term, 0, sizeof(term));
158  term.c_lflag |= ECHO;
159  memset(&oterm, 0, sizeof(oterm));
160  oterm.c_lflag |= ECHO;
161  }
162 
163  if (!(flags & RPP_STDIN))
164  (void)write(output, prompt, strlen(prompt));
165  end = buf + bufsiz - 1;
166  for (p = buf; (nr = read(input, &ch, 1)) == 1 && ch != '\n' && ch != '\r';) {
167  if (p < end) {
168  if ((flags & RPP_SEVENBIT))
169  ch &= 0x7f;
170  if (isalpha((unsigned char) ch)) {
171  if ((flags & RPP_FORCELOWER))
172  ch = tolower((unsigned char) ch);
173  if ((flags & RPP_FORCEUPPER))
174  ch = toupper((unsigned char) ch);
175  }
176  *p++ = ch;
177  }
178  }
179  *p = '\0';
180  save_errno = errno;
181  if (!(term.c_lflag & ECHO))
182  (void)write(output, "\n", 1);
183 
184  /* Restore old terminal settings and signals. */
185  if (memcmp(&term, &oterm, sizeof(term)) != 0)
186  (void)tcsetattr(input, _T_FLUSH, &oterm);
187  (void)sigaction(SIGALRM, &savealrm, NULL);
188  (void)sigaction(SIGHUP, &savehup, NULL);
189  (void)sigaction(SIGINT, &saveint, NULL);
190  (void)sigaction(SIGQUIT, &savequit, NULL);
191  (void)sigaction(SIGPIPE, &savepipe, NULL);
192  (void)sigaction(SIGTERM, &saveterm, NULL);
193  (void)sigaction(SIGTSTP, &savetstp, NULL);
194  (void)sigaction(SIGTTIN, &savettin, NULL);
195  if (input != STDIN_FILENO)
196  (void)close(input);
197 
198  /*
199  * If we were interrupted by a signal, resend it to ourselves
200  * now that we have restored the signal handlers.
201  */
202  if (signo) {
203  kill(getpid(), signo);
204  switch (signo) {
205  case SIGTSTP:
206  case SIGTTIN:
207  case SIGTTOU:
208  goto restart;
209  }
210  }
211 
212  errno = save_errno;
213  return(nr == -1 ? NULL : buf);
214 }
215 
216 #if 0
217 char *
218 getpass(const char *prompt)
219 {
220  static char buf[_PASSWORD_LEN + 1];
221 
222  return(readpassphrase(prompt, buf, sizeof(buf), RPP_ECHO_OFF));
223 }
224 #endif
225 
226 static void handler(int s)
227 {
228 
229  signo = s;
230 }
231 
232 #else /* _WIN32 */
233 
234 char *
235 tds_readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags)
236 {
237  int save_errno, ch;
238  char *p, *end;
239 
240  /* I suppose we could alloc on demand in this case (XXX). */
241  if (bufsiz == 0) {
242  errno = EINVAL;
243  return(NULL);
244  }
245 
246  printf("%s", prompt);
247  fflush(stdout);
248  end = buf + bufsiz - 1;
249  for (p = buf; (ch = getchar()) != EOF && ch != '\n' && ch != '\r';) {
250  if (p < end) {
251  ch &= 0xff;
252  if ((flags & RPP_SEVENBIT))
253  ch &= 0x7f;
254  if (isalpha(ch)) {
255  if ((flags & RPP_FORCELOWER))
256  ch = tolower(ch);
257  if ((flags & RPP_FORCEUPPER))
258  ch = toupper(ch);
259  }
260  *p++ = ch;
261  }
262  }
263  *p = '\0';
264  save_errno = errno;
265  printf("\n");
266  errno = save_errno;
267  return (ch == EOF ? NULL : buf);
268 }
269 
270 #endif /* _WIN32 */
271 
272 #endif /* HAVE_READPASSPHRASE */
static uch flags
constexpr auto end(const ct_const_array< T, N > &in) noexcept
int close(int fd)
Definition: connection.cpp:45
#define NULL
Definition: ncbistd.hpp:225
char * buf
#define ECHO
Definition: lex.newick.cpp:540
static int input()
#define STDIN_FILENO
Definition: ncbicgi.cpp:61
int ssize_t
Definition: ncbiconf_msvc.h:92
int isalpha(Uchar c)
Definition: ncbictype.hpp:61
int tolower(Uchar c)
Definition: ncbictype.hpp:72
int toupper(Uchar c)
Definition: ncbictype.hpp:73
static SQLCHAR output[256]
Definition: print.c:5
#define _T_FLUSH
char * tds_readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags)
#define _PATH_TTY
static volatile sig_atomic_t signo
static void handler(int)
#define readpassphrase
#define RPP_ECHO_ON
#define RPP_SEVENBIT
#define RPP_FORCEUPPER
#define RPP_STDIN
#define RPP_ECHO_OFF
#define RPP_REQUIRE_TTY
#define RPP_FORCELOWER
static char const rcsid[]
Modified on Sat Dec 02 09:22:39 2023 by modify_doxy.py rev. 669887