Home | History | Annotate | Line # | Download | only in liblutil
getpass.c revision 1.1.1.1.8.2
      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