2 * tfcrypt -- high security Threefish encryption tool.
4 * tfcrypt is copyrighted:
5 * Copyright (C) 2012-2018 Andrey Rys. All rights reserved.
7 * tfcrypt is licensed to you under the terms of std. MIT/X11 license:
9 * Permission is hereby granted, free of charge, to any person obtaining
10 * a copy of this software and associated documentation files (the
11 * "Software"), to deal in the Software without restriction, including
12 * without limitation the rights to use, copy, modify, merge, publish,
13 * distribute, sublicense, and/or sell copies of the Software, and to
14 * permit persons to whom the Software is furnished to do so, subject to
15 * the following conditions:
17 * The above copyright notice and this permission notice shall be
18 * included in all copies or substantial portions of the Software.
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
24 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 #include <sys/types.h>
37 #include "getpasswd.h"
39 size_t xgetpasswd(struct getpasswd_state *getps)
42 int tty_opened = 0, x;
45 size_t l, echolen = 0;
47 if (!getps) return ((size_t)-1);
50 * Both stdin and stderr point to same fd. This cannot happen.
51 * This only means that getps was memzero'd.
52 * Do not blame user for that, just fix it.
54 if ((getps->fd == 0 && getps->efd == 0) || getps->efd == -1) getps->efd = 2;
56 if (getps->fd == -1) {
57 if ((getps->fd = open("/dev/tty", O_RDONLY|O_NOCTTY)) == -1) getps->fd = 0;
61 memset(&t, 0, sizeof(struct termios));
62 memset(&s, 0, sizeof(struct termios));
63 if (tcgetattr(getps->fd, &t) == -1) {
68 if (getps->sanetty) memcpy(getps->sanetty, &s, sizeof(struct termios));
71 if (tcsetattr(getps->fd, TCSANOW, &t) == -1) {
77 echolen = strlen(getps->echo);
78 if (write(getps->efd, getps->echo, echolen) == -1) {
86 memset(getps->passwd, 0, getps->pwlen);
89 if (read(getps->fd, &c, sizeof(char)) == -1) {
94 if (getps->charfilter) {
95 x = getps->charfilter(getps, c, l);
100 else if (x == 2) continue;
101 else if (x == 3) goto _erase;
102 else if (x == 4) goto _delete;
103 else if (x == 5) break;
107 memset(getps->passwd, 0, getps->pwlen);
111 if (l >= getps->pwlen && (getps->flags & GETP_WAITFILL)) clear = 0;
114 || (c == '\x08' && !(getps->flags & GETP_NOINTERP))) { /* Backspace / ^H */
115 _erase: if (l == 0) continue;
118 if (!(getps->flags & GETP_NOECHO)) {
119 if (write(getps->efd, "\x08\033[1X", sizeof("\x08\033[1X")-1) == -1) {
120 getps->error = errno;
126 else if (!(getps->flags & GETP_NOINTERP)
127 && (c == '\x15' || c == '\x17')) { /* ^U / ^W */
130 memset(getps->passwd, 0, getps->pwlen);
131 if (write(getps->efd, "\033[2K\033[0G", sizeof("\033[2K\033[0G")-1) == -1) {
132 getps->error = errno;
137 if (write(getps->efd, getps->echo, echolen) == -1) {
138 getps->error = errno;
146 || (!(getps->flags & GETP_NOINTERP) && c == '\x04')) break;
148 *(getps->passwd+l) = c;
150 if (!(getps->flags & GETP_NOECHO)) {
151 if (getps->maskchar &&
152 write(getps->efd, &getps->maskchar,
153 sizeof(char)) == -1) {
154 getps->error = errno;
160 if (l >= getps->pwlen && !(getps->flags & GETP_WAITFILL)) break;
163 _err: if (write(getps->efd, "\r\n", sizeof("\r\n")-1) == -1) {
164 getps->error = errno;
167 if (x != 6) *(getps->passwd+l) = 0;
169 _xerr: if (tcsetattr(getps->fd, TCSANOW, &s) == -1) {
170 if (getps->error == 0) {
171 getps->error = errno;
176 if (tty_opened) close(getps->fd);