Mercurial > hg > toybox
comparison lib/password.c @ 1366:4cf313dbd885 draft
Cleanup read_password(), factor out set_terminal(), fix salt bug (des wants the salt raw, no $ at the beginning).
author | Rob Landley <rob@landley.net> |
---|---|
date | Sat, 28 Jun 2014 20:02:01 -0500 |
parents | e65f9a9ba62d |
children | cf77c4939385 |
comparison
equal
deleted
inserted
replaced
1365:2320af12ba95 | 1366:4cf313dbd885 |
---|---|
20 char *s = salt; | 20 char *s = salt; |
21 | 21 |
22 if (al[i].id) { | 22 if (al[i].id) { |
23 *s++ = '$'; | 23 *s++ = '$'; |
24 *s++ = '0'+al[i].id; | 24 *s++ = '0'+al[i].id; |
25 *s++ = '$'; | |
25 } | 26 } |
26 *s++ = '$'; | |
27 | 27 |
28 // Read appropriate number of random bytes for salt | 28 // Read appropriate number of random bytes for salt |
29 i = xopen("/dev/urandom", O_RDONLY); | 29 i = xopen("/dev/urandom", O_RDONLY); |
30 xreadall(i, libbuf, ((len*6)+7)/8); | 30 xreadall(i, libbuf, ((len*6)+7)/8); |
31 close(i); | 31 close(i); |
48 } | 48 } |
49 | 49 |
50 return -1; | 50 return -1; |
51 } | 51 } |
52 | 52 |
53 static void handle(int signo) | 53 // Reset terminal to known state, returning old state if old != NULL. |
54 { | 54 int set_terminal(int fd, int raw, struct termios *old) |
55 //Dummy.. so that read breaks on the signal, | 55 { |
56 //instead of the applocation exit | 56 struct termios termio; |
57 } | 57 |
58 | 58 if (!tcgetattr(fd, &termio) && old) *old = termio; |
59 int read_password(char * buff, int buflen, char* mesg) | 59 |
60 { | 60 // the following are the bits set for an xterm. Linux text mode TTYs by |
61 int i = 0; | 61 // default add two additional bits that only matter for serial processing |
62 struct termios termio, oldtermio; | 62 // (turn serial line break into an interrupt, and XON/XOFF flow control) |
63 | |
64 // Any key unblocks output, swap CR and NL on input | |
65 termio.c_iflag = IXANY|ICRNL|INLCR; | |
66 if (toys.which->flags & TOYFLAG_LOCALE) termio.c_iflag |= IUTF8; | |
67 | |
68 // Output appends CR to NL, does magic undocumented postprocessing | |
69 termio.c_oflag = ONLCR|OPOST; | |
70 | |
71 // Leave serial port speed alone | |
72 // termio.c_cflag = C_READ|CS8|EXTB; | |
73 | |
74 // Generate signals, input entire line at once, echo output | |
75 // erase, line kill, escape control characters with ^ | |
76 // erase line char at a time | |
77 // "extended" behavior: ctrl-V quotes next char, ctrl-R reprints unread chars, | |
78 // ctrl-W erases word | |
79 termio.c_lflag = ISIG|ICANON|ECHO|ECHOE|ECHOK|ECHOCTL|ECHOKE|IEXTEN; | |
80 | |
81 if (raw) cfmakeraw(&termio); | |
82 | |
83 return tcsetattr(fd, TCSANOW, &termio); | |
84 } | |
85 | |
86 // Prompt with mesg, read password into buf, return 0 for success 1 for fail | |
87 int read_password(char *buf, int buflen, char *mesg) | |
88 { | |
89 struct termios oldtermio; | |
63 struct sigaction sa, oldsa; | 90 struct sigaction sa, oldsa; |
64 | 91 int i, ret = 1; |
65 tcgetattr(0, &oldtermio); | 92 |
93 // NOP signal handler to return from the read | |
94 memset(&sa, 0, sizeof(sa)); | |
95 sa.sa_handler = generic_signal; | |
96 sigaction(SIGINT, &sa, &oldsa); | |
97 | |
66 tcflush(0, TCIFLUSH); | 98 tcflush(0, TCIFLUSH); |
67 termio = oldtermio; | 99 set_terminal(0, 1, &oldtermio); |
68 | 100 |
69 memset(&sa, 0, sizeof(sa)); | 101 xprintf("%s", mesg); |
70 sa.sa_handler = handle; | 102 |
71 sigaction(SIGINT, &sa, &oldsa); | 103 for (i=0; i < buflen-1; i++) { |
72 | 104 if ((ret = read(0, buf+i, 1)) < 0 || (!ret && !i)) { |
73 termio.c_iflag &= ~(IUCLC|IXON|IXOFF|IXANY); | 105 i = 0; |
74 termio.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|TOSTOP); | 106 ret = 1; |
75 tcsetattr(0, TCSANOW, &termio); | 107 |
76 | |
77 fputs(mesg, stdout); | |
78 fflush(stdout); | |
79 | |
80 while (1) { | |
81 int ret = read(0, &buff[i], 1); | |
82 if ( ret < 0 || (!ret && !i)) { | |
83 buff[0] = 0; | |
84 sigaction(SIGINT, &oldsa, NULL); | |
85 tcsetattr(0, TCSANOW, &oldtermio); | |
86 xputc('\n'); | |
87 fflush(stdout); | |
88 return 1; | |
89 } else if (ret == 0 || buff[i] == '\n' || buff[i] == '\r' || buflen == i+1) | |
90 { | |
91 buff[i] = '\0'; | |
92 break; | 108 break; |
93 } | 109 } else if (!ret || buf[i] == '\n' || buf[i] == '\r') { |
94 i++; | 110 ret = 0; |
95 } | 111 |
112 break; | |
113 } else if (buf[i] == 8 || buf[i] == 127) i -= i ? 2 : 1; | |
114 } | |
115 | |
116 // Restore terminal/signal state, terminate string | |
96 sigaction(SIGINT, &oldsa, NULL); | 117 sigaction(SIGINT, &oldsa, NULL); |
97 tcsetattr(0, TCSANOW, &oldtermio); | 118 tcsetattr(0, TCSANOW, &oldtermio); |
98 puts(""); | 119 buf[i] = 0; |
99 fflush(stdout); | 120 xputc('\n'); |
100 return 0; | 121 |
122 return ret; | |
101 } | 123 } |
102 | 124 |
103 static char *get_nextcolon(char *line, int cnt) | 125 static char *get_nextcolon(char *line, int cnt) |
104 { | 126 { |
105 while (cnt--) { | 127 while (cnt--) { |