File: | src/lib/libc/gen/readpassphrase.c |
Warning: | line 58, column 2 Value stored to 'nr' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* $OpenBSD: readpassphrase.c,v 1.27 2019/01/25 00:19:25 millert Exp $ */ |
2 | |
3 | /* |
4 | * Copyright (c) 2000-2002, 2007, 2010 |
5 | * Todd C. Miller <millert@openbsd.org> |
6 | * |
7 | * Permission to use, copy, modify, and distribute this software for any |
8 | * purpose with or without fee is hereby granted, provided that the above |
9 | * copyright notice and this permission notice appear in all copies. |
10 | * |
11 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
12 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
13 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
14 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
15 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
16 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
17 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
18 | * |
19 | * Sponsored in part by the Defense Advanced Research Projects |
20 | * Agency (DARPA) and Air Force Research Laboratory, Air Force |
21 | * Materiel Command, USAF, under agreement number F39502-99-1-0512. |
22 | */ |
23 | |
24 | #include <ctype.h> |
25 | #include <errno(*__errno()).h> |
26 | #include <fcntl.h> |
27 | #include <paths.h> |
28 | #include <pwd.h> |
29 | #include <signal.h> |
30 | #include <string.h> |
31 | #include <termios.h> |
32 | #include <unistd.h> |
33 | #include <readpassphrase.h> |
34 | |
35 | static volatile sig_atomic_t signo[_NSIG33]; |
36 | |
37 | static void handler(int); |
38 | |
39 | char * |
40 | readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags) |
41 | { |
42 | ssize_t nr; |
43 | int input, output, save_errno, i, need_restart; |
44 | char ch, *p, *end; |
45 | struct termios term, oterm; |
46 | struct sigaction sa, savealrm, saveint, savehup, savequit, saveterm; |
47 | struct sigaction savetstp, savettin, savettou, savepipe; |
48 | |
49 | /* I suppose we could alloc on demand in this case (XXX). */ |
50 | if (bufsiz == 0) { |
51 | errno(*__errno()) = EINVAL22; |
52 | return(NULL((void *)0)); |
53 | } |
54 | |
55 | restart: |
56 | for (i = 0; i < _NSIG33; i++) |
57 | signo[i] = 0; |
58 | nr = -1; |
Value stored to 'nr' is never read | |
59 | save_errno = 0; |
60 | need_restart = 0; |
61 | /* |
62 | * Read and write to /dev/tty if available. If not, read from |
63 | * stdin and write to stderr unless a tty is required. |
64 | */ |
65 | if ((flags & RPP_STDIN0x20) || |
66 | (input = output = open(_PATH_TTY"/dev/tty", O_RDWR0x0002)) == -1) { |
67 | if (flags & RPP_REQUIRE_TTY0x02) { |
68 | errno(*__errno()) = ENOTTY25; |
69 | return(NULL((void *)0)); |
70 | } |
71 | input = STDIN_FILENO0; |
72 | output = STDERR_FILENO2; |
73 | } |
74 | |
75 | /* |
76 | * Turn off echo if possible. |
77 | * If we are using a tty but are not the foreground pgrp this will |
78 | * generate SIGTTOU, so do it *before* installing the signal handlers. |
79 | */ |
80 | if (input != STDIN_FILENO0 && tcgetattr(input, &oterm) == 0) { |
81 | memcpy(&term, &oterm, sizeof(term)); |
82 | if (!(flags & RPP_ECHO_ON0x01)) |
83 | term.c_lflag &= ~(ECHO0x00000008 | ECHONL0x00000010); |
84 | if (term.c_cc[VSTATUS18] != _POSIX_VDISABLE(0377)) |
85 | term.c_cc[VSTATUS18] = _POSIX_VDISABLE(0377); |
86 | (void)tcsetattr(input, TCSAFLUSH2|TCSASOFT0x10, &term); |
87 | } else { |
88 | memset(&term, 0, sizeof(term)); |
89 | term.c_lflag |= ECHO0x00000008; |
90 | memset(&oterm, 0, sizeof(oterm)); |
91 | oterm.c_lflag |= ECHO0x00000008; |
92 | } |
93 | |
94 | /* |
95 | * Catch signals that would otherwise cause the user to end |
96 | * up with echo turned off in the shell. Don't worry about |
97 | * things like SIGXCPU and SIGVTALRM for now. |
98 | */ |
99 | sigemptyset(&sa.sa_mask); |
100 | sa.sa_flags = 0; /* don't restart system calls */ |
101 | sa.sa_handler__sigaction_u.__sa_handler = handler; |
102 | (void)sigaction(SIGALRM14, &sa, &savealrm); |
103 | (void)sigaction(SIGHUP1, &sa, &savehup); |
104 | (void)sigaction(SIGINT2, &sa, &saveint); |
105 | (void)sigaction(SIGPIPE13, &sa, &savepipe); |
106 | (void)sigaction(SIGQUIT3, &sa, &savequit); |
107 | (void)sigaction(SIGTERM15, &sa, &saveterm); |
108 | (void)sigaction(SIGTSTP18, &sa, &savetstp); |
109 | (void)sigaction(SIGTTIN21, &sa, &savettin); |
110 | (void)sigaction(SIGTTOU22, &sa, &savettou); |
111 | |
112 | if (!(flags & RPP_STDIN0x20)) |
113 | (void)write(output, prompt, strlen(prompt)); |
114 | end = buf + bufsiz - 1; |
115 | p = buf; |
116 | while ((nr = read(input, &ch, 1)) == 1 && ch != '\n' && ch != '\r') { |
117 | if (p < end) { |
118 | if ((flags & RPP_SEVENBIT0x10)) |
119 | ch &= 0x7f; |
120 | if (isalpha((unsigned char)ch)) { |
121 | if ((flags & RPP_FORCELOWER0x04)) |
122 | ch = (char)tolower((unsigned char)ch); |
123 | if ((flags & RPP_FORCEUPPER0x08)) |
124 | ch = (char)toupper((unsigned char)ch); |
125 | } |
126 | *p++ = ch; |
127 | } |
128 | } |
129 | *p = '\0'; |
130 | save_errno = errno(*__errno()); |
131 | if (!(term.c_lflag & ECHO0x00000008)) |
132 | (void)write(output, "\n", 1); |
133 | |
134 | /* Restore old terminal settings and signals. */ |
135 | if (memcmp(&term, &oterm, sizeof(term)) != 0) { |
136 | const int sigttou = signo[SIGTTOU22]; |
137 | |
138 | /* Ignore SIGTTOU generated when we are not the fg pgrp. */ |
139 | while (tcsetattr(input, TCSAFLUSH2|TCSASOFT0x10, &oterm) == -1 && |
140 | errno(*__errno()) == EINTR4 && !signo[SIGTTOU22]) |
141 | continue; |
142 | signo[SIGTTOU22] = sigttou; |
143 | } |
144 | (void)sigaction(SIGALRM14, &savealrm, NULL((void *)0)); |
145 | (void)sigaction(SIGHUP1, &savehup, NULL((void *)0)); |
146 | (void)sigaction(SIGINT2, &saveint, NULL((void *)0)); |
147 | (void)sigaction(SIGQUIT3, &savequit, NULL((void *)0)); |
148 | (void)sigaction(SIGPIPE13, &savepipe, NULL((void *)0)); |
149 | (void)sigaction(SIGTERM15, &saveterm, NULL((void *)0)); |
150 | (void)sigaction(SIGTSTP18, &savetstp, NULL((void *)0)); |
151 | (void)sigaction(SIGTTIN21, &savettin, NULL((void *)0)); |
152 | (void)sigaction(SIGTTOU22, &savettou, NULL((void *)0)); |
153 | if (input != STDIN_FILENO0) |
154 | (void)close(input); |
155 | |
156 | /* |
157 | * If we were interrupted by a signal, resend it to ourselves |
158 | * now that we have restored the signal handlers. |
159 | */ |
160 | for (i = 0; i < _NSIG33; i++) { |
161 | if (signo[i]) { |
162 | kill(getpid(), i); |
163 | switch (i) { |
164 | case SIGTSTP18: |
165 | case SIGTTIN21: |
166 | case SIGTTOU22: |
167 | need_restart = 1; |
168 | } |
169 | } |
170 | } |
171 | if (need_restart) |
172 | goto restart; |
173 | |
174 | if (save_errno) |
175 | errno(*__errno()) = save_errno; |
176 | return(nr == -1 ? NULL((void *)0) : buf); |
177 | } |
178 | DEF_WEAK(readpassphrase)__asm__(".weak " "readpassphrase" " ; " "readpassphrase" " = " "_libc_readpassphrase"); |
179 | |
180 | char * |
181 | getpass(const char *prompt) |
182 | { |
183 | static char buf[_PASSWORD_LEN128 + 1]; |
184 | |
185 | return(readpassphrase(prompt, buf, sizeof(buf), RPP_ECHO_OFF0x00)); |
186 | } |
187 | |
188 | static void handler(int s) |
189 | { |
190 | |
191 | signo[s] = 1; |
192 | } |