1 /* $NetBSD: ui.c,v 1.2 2017/01/28 21:31:47 christos Exp $ */ 2 3 /* 4 * Copyright (c) 1997 - 2000, 2005 Kungliga Tekniska Högskolan 5 * (Royal Institute of Technology, Stockholm, Sweden). 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * 3. Neither the name of the Institute nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36 #include <config.h> 37 #include <krb5/roken.h> 38 #include <signal.h> 39 #ifdef HAVE_TERMIOS_H 40 #include <termios.h> 41 #endif 42 43 #include <ui.h> 44 #ifdef HAVE_CONIO_H 45 #include <conio.h> 46 #endif 47 48 static sig_atomic_t intr_flag; 49 50 static void 51 intr(int sig) 52 { 53 intr_flag++; 54 } 55 56 #ifdef HAVE_CONIO_H 57 58 /* 59 * Windows does console slightly different then then unix case. 60 */ 61 62 static int 63 read_string(const char *preprompt, const char *prompt, 64 char *buf, size_t len, int echo) 65 { 66 int of = 0; 67 int c; 68 char *p; 69 void (*oldsigintr)(int); 70 71 _cprintf("%s%s", preprompt, prompt); 72 73 oldsigintr = signal(SIGINT, intr); 74 75 p = buf; 76 while(intr_flag == 0){ 77 c = ((echo)? _getche(): _getch()); 78 if(c == '\n' || c == '\r') 79 break; 80 if(of == 0) 81 *p++ = c; 82 of = (p == buf + len); 83 } 84 if(of) 85 p--; 86 *p = 0; 87 88 if(echo == 0){ 89 printf("\n"); 90 } 91 92 signal(SIGINT, oldsigintr); 93 94 if(intr_flag) 95 return -2; 96 if(of) 97 return -1; 98 return 0; 99 } 100 101 #else /* !HAVE_CONIO_H */ 102 103 #ifndef NSIG 104 #define NSIG 47 105 #endif 106 107 static int 108 read_string(const char *preprompt, const char *prompt, 109 char *buf, size_t len, int echo) 110 { 111 struct sigaction sigs[NSIG]; 112 int oksigs[NSIG]; 113 struct sigaction sa; 114 FILE *tty; 115 int ret = 0; 116 int of = 0; 117 int i; 118 int c; 119 char *p; 120 121 struct termios t_new, t_old; 122 123 memset(&oksigs, 0, sizeof(oksigs)); 124 125 memset(&sa, 0, sizeof(sa)); 126 sa.sa_handler = intr; 127 sigemptyset(&sa.sa_mask); 128 sa.sa_flags = 0; 129 for(i = 1; i < sizeof(sigs) / sizeof(sigs[0]); i++) 130 if (i != SIGALRM) 131 if (sigaction(i, &sa, &sigs[i]) == 0) 132 oksigs[i] = 1; 133 134 if((tty = fopen("/dev/tty", "r")) != NULL) 135 rk_cloexec_file(tty); 136 else 137 tty = stdin; 138 139 fprintf(stderr, "%s%s", preprompt, prompt); 140 fflush(stderr); 141 142 if(echo == 0){ 143 tcgetattr(fileno(tty), &t_old); 144 memcpy(&t_new, &t_old, sizeof(t_new)); 145 t_new.c_lflag &= ~ECHO; 146 tcsetattr(fileno(tty), TCSANOW, &t_new); 147 } 148 intr_flag = 0; 149 p = buf; 150 while(intr_flag == 0){ 151 c = getc(tty); 152 if(c == EOF){ 153 if(!ferror(tty)) 154 ret = 1; 155 break; 156 } 157 if(c == '\n') 158 break; 159 if(of == 0) 160 *p++ = c; 161 of = (p == buf + len); 162 } 163 if(of) 164 p--; 165 *p = 0; 166 167 if(echo == 0){ 168 fprintf(stderr, "\n"); 169 tcsetattr(fileno(tty), TCSANOW, &t_old); 170 } 171 172 if(tty != stdin) 173 fclose(tty); 174 175 for(i = 1; i < sizeof(sigs) / sizeof(sigs[0]); i++) 176 if (oksigs[i]) 177 sigaction(i, &sigs[i], NULL); 178 179 if(ret) 180 return -3; 181 if(intr_flag) 182 return -2; 183 if(of) 184 return -1; 185 return 0; 186 } 187 188 #endif /* HAVE_CONIO_H */ 189 190 int 191 UI_UTIL_read_pw_string(char *buf, int length, const char *prompt, int verify) 192 { 193 int ret; 194 195 ret = read_string("", prompt, buf, length, 0); 196 if (ret) 197 return ret; 198 199 if (verify) { 200 char *buf2; 201 buf2 = malloc(length); 202 if (buf2 == NULL) 203 return 1; 204 205 ret = read_string("Verify password - ", prompt, buf2, length, 0); 206 if (ret) { 207 free(buf2); 208 return ret; 209 } 210 if (strcmp(buf2, buf) != 0) 211 ret = 1; 212 free(buf2); 213 } 214 return ret; 215 } 216