1 /* 2 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 #pragma ident "%Z%%M% %I% %E% SMI" 7 8 /* 9 * lib/krb5/os/read_pwd.c 10 * 11 * Copyright 1990,1991 by the Massachusetts Institute of Technology. 12 * All Rights Reserved. 13 * 14 * Export of this software from the United States of America may 15 * require a specific license from the United States Government. 16 * It is the responsibility of any person or organization contemplating 17 * export to obtain such a license before exporting. 18 * 19 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 20 * distribute this software and its documentation for any purpose and 21 * without fee is hereby granted, provided that the above copyright 22 * notice appear in all copies and that both that copyright notice and 23 * this permission notice appear in supporting documentation, and that 24 * the name of M.I.T. not be used in advertising or publicity pertaining 25 * to distribution of the software without specific, written prior 26 * permission. Furthermore if you modify this software you must label 27 * your software as modified software and not distribute it in such a 28 * fashion that it might be confused with the original M.I.T. software. 29 * M.I.T. makes no representations about the suitability of 30 * this software for any purpose. It is provided "as is" without express 31 * or implied warranty. 32 * 33 * 34 * libos: krb5_read_password for BSD 4.3 35 */ 36 37 #include <k5-int.h> 38 39 #if !defined(_MSDOS) && !defined(_WIN32) && !defined(macintosh) 40 #define DEFINED_KRB5_READ_PASSWORD 41 #include <stdio.h> 42 #include <errno.h> 43 #include <signal.h> 44 #include <setjmp.h> 45 /* 46 * Solaris kerberos: include this for internationalization 47 */ 48 #include <libintl.h> 49 50 #ifndef ECHO_PASSWORD 51 #include <termios.h> 52 #endif /* ECHO_PASSWORD */ 53 54 static jmp_buf pwd_jump; 55 56 /*ARGSUSED*/ 57 static krb5_sigtype 58 intr_routine(signo) 59 int signo; 60 { 61 longjmp(pwd_jump, 1); 62 /*NOTREACHED*/ 63 } 64 65 /*ARGSUSED*/ 66 krb5_error_code 67 krb5_read_password(context, prompt, prompt2, return_pwd, size_return) 68 krb5_context context; 69 const char *prompt; 70 const char *prompt2; 71 char *return_pwd; 72 unsigned int *size_return; 73 { 74 /* adapted from Kerberos v4 des/read_password.c */ 75 /* readin_string is used after a longjmp, so must be volatile */ 76 char *volatile readin_string = 0; 77 register char *ptr; 78 int scratchchar; 79 krb5_sigtype (*volatile ointrfunc)(); 80 krb5_error_code errcode; 81 #ifndef ECHO_PASSWORD 82 struct termios echo_control, save_control; 83 int fd; 84 85 /* get the file descriptor associated with stdin */ 86 fd=fileno(stdin); 87 88 if (tcgetattr(fd, &echo_control) == -1) 89 return errno; 90 91 save_control = echo_control; 92 echo_control.c_lflag &= ~(ECHO|ECHONL); 93 94 if (tcsetattr(fd, TCSANOW, &echo_control) == -1) 95 return errno; 96 #endif /* ECHO_PASSWORD */ 97 98 if (setjmp(pwd_jump)) { 99 errcode = KRB5_LIBOS_PWDINTR; /* we were interrupted... */ 100 goto cleanup; 101 } 102 /* save intrfunc */ 103 ointrfunc = signal(SIGINT, intr_routine); 104 105 /* put out the prompt */ 106 (void) fputs(dgettext(TEXT_DOMAIN, prompt), stdout); 107 (void) fflush(stdout); 108 (void) memset(return_pwd, 0, *size_return); 109 110 if (fgets(return_pwd, *size_return, stdin) == NULL) { 111 (void) putchar('\n'); 112 errcode = KRB5_LIBOS_CANTREADPWD; 113 goto cleanup; 114 } 115 (void) putchar('\n'); 116 /* fgets always null-terminates the returned string */ 117 118 /* replace newline with null */ 119 if ((ptr = strchr(return_pwd, '\n'))) 120 *ptr = '\0'; 121 else /* flush rest of input line */ 122 do { 123 scratchchar = getchar(); 124 } while (scratchchar != EOF && scratchchar != '\n'); 125 126 if (prompt2) { 127 /* put out the prompt */ 128 (void) fputs(dgettext(TEXT_DOMAIN, prompt2), stdout); 129 (void) fflush(stdout); 130 readin_string = malloc(*size_return); 131 if (!readin_string) { 132 errcode = ENOMEM; 133 goto cleanup; 134 } 135 (void) memset((char *)readin_string, 0, *size_return); 136 if (fgets((char *)readin_string, *size_return, stdin) == NULL) { 137 (void) putchar('\n'); 138 errcode = KRB5_LIBOS_CANTREADPWD; 139 goto cleanup; 140 } 141 (void) putchar('\n'); 142 143 if ((ptr = strchr((char *)readin_string, '\n'))) 144 *ptr = '\0'; 145 else /* need to flush */ 146 do { 147 scratchchar = getchar(); 148 } while (scratchchar != EOF && scratchchar != '\n'); 149 150 /* compare */ 151 if (strncmp(return_pwd, (char *)readin_string, *size_return)) { 152 errcode = KRB5_LIBOS_BADPWDMATCH; 153 goto cleanup; 154 } 155 } 156 157 errcode = 0; 158 159 cleanup: 160 (void) signal(SIGINT, ointrfunc); 161 #ifndef ECHO_PASSWORD 162 if ((tcsetattr(fd, TCSANOW, &save_control) == -1) && 163 errcode == 0) 164 return errno; 165 #endif 166 if (readin_string) { 167 memset((char *)readin_string, 0, *size_return); 168 krb5_xfree(readin_string); 169 } 170 if (errcode) 171 memset(return_pwd, 0, *size_return); 172 else 173 *size_return = strlen(return_pwd); 174 return errcode; 175 } 176 #else /* MSDOS */ 177 178 #ifndef DEFINED_KRB5_READ_PASSWORD 179 #define DEFINED_KRB5_READ_PASSWORD 180 /* 181 * Don't expect to be called, just define it for sanity and the linker. 182 */ 183 KRB5_DLLIMP krb5_error_code KRB5_CALLCONV 184 krb5_read_password(context, prompt, prompt2, return_pwd, size_return) 185 krb5_context context; 186 const char *prompt; 187 const char *prompt2; 188 char *return_pwd; 189 int *size_return; 190 { 191 *size_return = 0; 192 return KRB5_LIBOS_CANTREADPWD; 193 } 194 #endif /* DEFINED_KRB5_READ_PASSWORD */ 195 196 #endif /* MSDOS */ 197