1 /* getpass.c -- get password from user */ 2 /* $OpenLDAP: pkg/ldap/libraries/liblutil/getpass.c,v 1.17.2.3 2008/02/11 23:26:42 kurt Exp $ */ 3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>. 4 * 5 * Copyright 1998-2008 The OpenLDAP Foundation. 6 * Portions Copyright 1998-2003 Kurt D. Zeilenga. 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted only as authorized by the OpenLDAP 11 * Public License. 12 * 13 * A copy of this license is available in the file LICENSE in the 14 * top-level directory of the distribution or, alternatively, at 15 * <http://www.OpenLDAP.org/license.html>. 16 */ 17 /* Portions Copyright (c) 1992, 1993 Regents of the University of Michigan. 18 * All rights reserved. 19 * 20 * Redistribution and use in source and binary forms are permitted 21 * provided that this notice is preserved and that due credit is given 22 * to the University of Michigan at Ann Arbor. The name of the University 23 * may not be used to endorse or promote products derived from this 24 * software without specific prior written permission. This software 25 * is provided ``as is'' without express or implied warranty. 26 */ 27 /* This work was originally developed by the University of Michigan 28 * and distributed as part of U-MICH LDAP. It was adapted for use in 29 * -llutil by Kurt D. Zeilenga. 30 */ 31 32 #include "portable.h" 33 34 #include <stdio.h> 35 36 #include <ac/stdlib.h> 37 38 #include <ac/ctype.h> 39 #include <ac/signal.h> 40 #include <ac/string.h> 41 #include <ac/termios.h> 42 #include <ac/time.h> 43 #include <ac/unistd.h> 44 45 #ifdef NEED_GETPASSPHRASE 46 47 #ifdef HAVE_FCNTL_H 48 #include <fcntl.h> 49 #endif 50 51 #ifdef HAVE_CONIO_H 52 #include <conio.h> 53 #endif 54 55 #include <lber.h> 56 #include <ldap.h> 57 58 #include "ldap_defaults.h" 59 60 char * 61 lutil_getpass( const char *prompt ) 62 { 63 #if !defined(HAVE_TERMIOS_H) && !defined(HAVE_SGTTY_H) 64 static char buf[256]; 65 int i, c; 66 67 if( prompt == NULL ) prompt = _("Password: "); 68 69 #ifdef DEBUG 70 if (debug & D_TRACE) 71 printf("->getpass(%s)\n", prompt); 72 #endif 73 74 printf("%s", prompt); 75 i = 0; 76 while ( (c = getch()) != EOF && c != '\n' && c != '\r' ) 77 buf[i++] = c; 78 if ( c == EOF ) 79 return( NULL ); 80 buf[i] = '\0'; 81 return (buf); 82 #else 83 int no_pass = 0; 84 char i, j, k; 85 TERMIO_TYPE ttyb; 86 TERMFLAG_TYPE flags; 87 static char pbuf[513]; 88 register char *p; 89 register int c; 90 FILE *fi; 91 RETSIGTYPE (*sig)( int sig ); 92 93 if( prompt == NULL ) prompt = _("Password: "); 94 95 #ifdef DEBUG 96 if (debug & D_TRACE) 97 printf("->getpass(%s)\n", prompt); 98 #endif 99 /* 100 * Stolen from the getpass() routine. Can't use the plain 101 * getpass() for two reasons. One is that LDAP passwords 102 * can be really, really long - much longer than 8 chars. 103 * The second is that we like to make this client available 104 * out of inetd via a Merit asynch port, and we need to be 105 * able to do telnet control codes to turn on and off line 106 * blanking. 107 */ 108 if ((fi = fdopen(open("/dev/tty", 2), "r")) == NULL) 109 fi = stdin; 110 else 111 setbuf(fi, (char *)NULL); 112 sig = SIGNAL (SIGINT, SIG_IGN); 113 if (fi != stdin) { 114 if (GETATTR(fileno(fi), &ttyb) < 0) 115 perror("GETATTR"); 116 } 117 flags = GETFLAGS( ttyb ); 118 SETFLAGS( ttyb, flags & ~ECHO ); 119 if (fi != stdin) { 120 if (SETATTR(fileno(fi), &ttyb) < 0) 121 perror("SETATTR"); 122 } 123 124 /* blank the line if through Merit */ 125 if (fi == stdin) { 126 printf("%c%c%c", 255, 251, 1); 127 fflush(stdout); 128 (void) scanf("%c%c%c", &i, &j, &k); 129 fflush(stdin); 130 } 131 132 /* fetch the password */ 133 fprintf(stdout, "%s", prompt); 134 fflush(stdout); 135 for (p=pbuf; (c = getc(fi))!='\n' && c!=EOF;) { 136 if (c == '\r') 137 break; 138 if (p < &pbuf[512]) 139 *p++ = c; 140 } 141 if (c == EOF) 142 no_pass = 1; 143 else { 144 *p = '\0'; 145 if (*(p - 1) == '\r') 146 *(p - 1) = '\0'; 147 } 148 149 /* unblank the line if through Merit */ 150 if (fi == stdin) { 151 printf("%c%c%c", 255, 252, 1); 152 fflush(stdout); 153 (void) scanf("%c%c%c", &i, &j, &k); 154 fflush(stdin); 155 printf("\n"); fflush(stdout); 156 } 157 fprintf(stdout, "\n"); 158 fflush(stdout); 159 160 /* tidy up */ 161 SETFLAGS( ttyb, flags ); 162 if (fi != stdin) { 163 if (SETATTR(fileno(fi), &ttyb) < 0) 164 perror("SETATTR"); 165 } 166 (void) SIGNAL (SIGINT, sig); 167 if (fi != stdin) 168 (void) fclose(fi); 169 else 170 i = getchar(); 171 if (no_pass) 172 return(NULL); 173 return(pbuf); 174 #endif 175 } 176 177 #endif /* !NEED_GETPASSPHRASE */ 178