1 /* $NetBSD: ui.c,v 1.1.1.1 2011/04/13 18:14:50 elric 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 38 #include <stdio.h> 39 #include <stdlib.h> 40 #include <string.h> 41 #include <signal.h> 42 #ifdef HAVE_TERMIOS_H 43 #include <termios.h> 44 #endif 45 #include <krb5/roken.h> 46 47 #include <ui.h> 48 #ifdef HAVE_CONIO_H 49 #include <conio.h> 50 #endif 51 52 static sig_atomic_t intr_flag; 53 54 static void 55 intr(int sig) 56 { 57 intr_flag++; 58 } 59 60 #ifdef HAVE_CONIO_H 61 62 /* 63 * Windows does console slightly different then then unix case. 64 */ 65 66 static int 67 read_string(const char *preprompt, const char *prompt, 68 char *buf, size_t len, int echo) 69 { 70 int of = 0; 71 int c; 72 char *p; 73 void (*oldsigintr)(int); 74 75 _cprintf("%s%s", preprompt, prompt); 76 77 oldsigintr = signal(SIGINT, intr); 78 79 p = buf; 80 while(intr_flag == 0){ 81 c = ((echo)? _getche(): _getch()); 82 if(c == '\n' || c == '\r') 83 break; 84 if(of == 0) 85 *p++ = c; 86 of = (p == buf + len); 87 } 88 if(of) 89 p--; 90 *p = 0; 91 92 if(echo == 0){ 93 printf("\n"); 94 } 95 96 signal(SIGINT, oldsigintr); 97 98 if(intr_flag) 99 return -2; 100 if(of) 101 return -1; 102 return 0; 103 } 104 105 #else /* !HAVE_CONIO_H */ 106 107 #ifndef NSIG 108 #define NSIG 47 109 #endif 110 111 static int 112 read_string(const char *preprompt, const char *prompt, 113 char *buf, size_t len, int echo) 114 { 115 struct sigaction sigs[NSIG]; 116 int oksigs[NSIG]; 117 struct sigaction sa; 118 FILE *tty; 119 int ret = 0; 120 int of = 0; 121 int i; 122 int c; 123 char *p; 124 125 struct termios t_new, t_old; 126 127 memset(&oksigs, 0, sizeof(oksigs)); 128 129 memset(&sa, 0, sizeof(sa)); 130 sa.sa_handler = intr; 131 sigemptyset(&sa.sa_mask); 132 sa.sa_flags = 0; 133 for(i = 1; i < sizeof(sigs) / sizeof(sigs[0]); i++) 134 if (i != SIGALRM) 135 if (sigaction(i, &sa, &sigs[i]) == 0) 136 oksigs[i] = 1; 137 138 if((tty = fopen("/dev/tty", "r")) != NULL) 139 rk_cloexec_file(tty); 140 else 141 tty = stdin; 142 143 fprintf(stderr, "%s%s", preprompt, prompt); 144 fflush(stderr); 145 146 if(echo == 0){ 147 tcgetattr(fileno(tty), &t_old); 148 memcpy(&t_new, &t_old, sizeof(t_new)); 149 t_new.c_lflag &= ~ECHO; 150 tcsetattr(fileno(tty), TCSANOW, &t_new); 151 } 152 intr_flag = 0; 153 p = buf; 154 while(intr_flag == 0){ 155 c = getc(tty); 156 if(c == EOF){ 157 if(!ferror(tty)) 158 ret = 1; 159 break; 160 } 161 if(c == '\n') 162 break; 163 if(of == 0) 164 *p++ = c; 165 of = (p == buf + len); 166 } 167 if(of) 168 p--; 169 *p = 0; 170 171 if(echo == 0){ 172 fprintf(stderr, "\n"); 173 tcsetattr(fileno(tty), TCSANOW, &t_old); 174 } 175 176 if(tty != stdin) 177 fclose(tty); 178 179 for(i = 1; i < sizeof(sigs) / sizeof(sigs[0]); i++) 180 if (oksigs[i]) 181 sigaction(i, &sigs[i], NULL); 182 183 if(ret) 184 return -3; 185 if(intr_flag) 186 return -2; 187 if(of) 188 return -1; 189 return 0; 190 } 191 192 #endif /* HAVE_CONIO_H */ 193 194 int 195 UI_UTIL_read_pw_string(char *buf, int length, const char *prompt, int verify) 196 { 197 int ret; 198 199 ret = read_string("", prompt, buf, length, 0); 200 if (ret) 201 return ret; 202 203 if (verify) { 204 char *buf2; 205 buf2 = malloc(length); 206 if (buf2 == NULL) 207 return 1; 208 209 ret = read_string("Verify password - ", prompt, buf2, length, 0); 210 if (ret) { 211 free(buf2); 212 return ret; 213 } 214 if (strcmp(buf2, buf) != 0) 215 ret = 1; 216 free(buf2); 217 } 218 return ret; 219 } 220