mirror of
https://github.com/moparisthebest/curl
synced 2024-12-21 23:58:49 -05:00
My reimplementation and cleanup of the getpass source code. We officially no
longer use Angus Mackay's getpass code due to the weirdo license his code was donated to us under.
This commit is contained in:
parent
695f95aad1
commit
7ef6b05ef1
@ -1263,13 +1263,12 @@ AC_CHECK_FUNCS( strtoll \
|
|||||||
inet_addr \
|
inet_addr \
|
||||||
inet_ntoa \
|
inet_ntoa \
|
||||||
inet_pton \
|
inet_pton \
|
||||||
tcsetattr \
|
|
||||||
tcgetattr \
|
|
||||||
perror \
|
perror \
|
||||||
closesocket \
|
closesocket \
|
||||||
siginterrupt \
|
siginterrupt \
|
||||||
sigaction \
|
sigaction \
|
||||||
signal \
|
signal \
|
||||||
|
getpass \
|
||||||
getpass_r \
|
getpass_r \
|
||||||
strlcat \
|
strlcat \
|
||||||
getpwuid \
|
getpwuid \
|
||||||
|
324
src/getpass.c
324
src/getpass.c
@ -1,47 +1,73 @@
|
|||||||
/* ============================================================================
|
/***************************************************************************
|
||||||
|
* _ _ ____ _
|
||||||
|
* Project ___| | | | _ \| |
|
||||||
|
* / __| | | | |_) | |
|
||||||
|
* | (__| |_| | _ <| |___
|
||||||
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Redistribution and use are freely permitted provided that:
|
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* 1) This header remain in tact.
|
* This software is licensed as described in the file COPYING, which
|
||||||
* 2) The prototypes for getpass and getpass_r are not changed from:
|
* you should have received as part of this distribution. The terms
|
||||||
* char *getpass(const char *prompt)
|
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||||
* char *getpass_r(const char *prompt, char* buffer, int buflen)
|
|
||||||
* 3) This source code is not used outside of this(getpass.c) file.
|
|
||||||
* 4) Any changes to this(getpass.c) source code are made publicly available.
|
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
|
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
* copies of the Software, and permit persons to whom the Software is
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
* furnished to do so, under the terms of the COPYING file.
|
||||||
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
*
|
||||||
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
* KIND, either express or implied.
|
||||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
* POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
* ============================================================================
|
|
||||||
*
|
*
|
||||||
* $Id$
|
* $Id$
|
||||||
*
|
***************************************************************************/
|
||||||
* The spirit of this license is to allow use of this source code in any
|
|
||||||
* project be it open or closed but still encourage the use of the open,
|
|
||||||
* library based equivilents.
|
|
||||||
*
|
|
||||||
* Author(s):
|
|
||||||
* Angus Mackay <amackay@gus.ml.org>
|
|
||||||
* Daniel Stenberg <daniel@haxx.se>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "setup.h" /* setup.h is required for read() prototype */
|
/* This file is a reimplementation of the previous one, due to license
|
||||||
|
problems. */
|
||||||
|
|
||||||
|
#include "setup.h"
|
||||||
|
|
||||||
#ifndef HAVE_GETPASS_R
|
#ifndef HAVE_GETPASS_R
|
||||||
|
/* this file is only for systems without getpass_r() */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_UNISTD_H
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "getpass.h"
|
#include "getpass.h"
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifdef HAVE_GETPASS
|
||||||
#ifdef VMS
|
char *getpass_r(const char *prompt, char *password, size_t passlen)
|
||||||
#include <stdio.h>
|
{
|
||||||
#include <string.h>
|
char *ptr = getpass(prompt);
|
||||||
|
strncpy(password, ptr, passlen);
|
||||||
|
password[passlen-1]=0;
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
#define DONE
|
||||||
|
#else
|
||||||
|
/* the rest of this file is only for systems without getpass() */
|
||||||
|
|
||||||
|
#ifdef HAVE_FCNTL_H
|
||||||
|
#include <fcntl.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_TERMIOS_H
|
||||||
|
#include <termios.h>
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_TERMIO_H
|
||||||
|
#include <termio.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The last #include file should be: */
|
||||||
|
#if defined(CURLDEBUG) && defined(CURLTOOLDEBUG)
|
||||||
|
#include "memdebug.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef VMS
|
||||||
|
/* VMS implementation */
|
||||||
#include descrip
|
#include descrip
|
||||||
#include starlet
|
#include starlet
|
||||||
#include iodef
|
#include iodef
|
||||||
@ -78,139 +104,16 @@ char *getpass_r(const char *prompt, char *buffer, size_t buflen)
|
|||||||
}
|
}
|
||||||
return buffer; /* we always return success */
|
return buffer; /* we always return success */
|
||||||
}
|
}
|
||||||
#else /* VMS */
|
#define DONE
|
||||||
#ifdef HAVE_TERMIOS_H
|
|
||||||
# if !defined(HAVE_TCGETATTR) && !defined(HAVE_TCSETATTR)
|
|
||||||
# undef HAVE_TERMIOS_H
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef RETSIGTYPE
|
|
||||||
# define RETSIGTYPE void
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_UNISTD_H
|
|
||||||
#include <unistd.h>
|
|
||||||
#endif
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <signal.h>
|
|
||||||
#ifdef HAVE_TERMIOS_H
|
|
||||||
# include <termios.h>
|
|
||||||
#else
|
|
||||||
# ifdef HAVE_TERMIO_H
|
|
||||||
# include <termio.h>
|
|
||||||
# else
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* The last #include file should be: */
|
|
||||||
#if defined(CURLDEBUG) && defined(CURLTOOLDEBUG)
|
|
||||||
#include "memdebug.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
char *getpass_r(const char *prompt, char *buffer, size_t buflen)
|
|
||||||
{
|
|
||||||
FILE *infp;
|
|
||||||
char infp_fclose = 0;
|
|
||||||
FILE *outfp;
|
|
||||||
RETSIGTYPE (*sigint)(int);
|
|
||||||
#ifdef SIGTSTP
|
|
||||||
RETSIGTYPE (*sigtstp)(int);
|
|
||||||
#endif
|
|
||||||
size_t bytes_read;
|
|
||||||
int infd;
|
|
||||||
int outfd;
|
|
||||||
#ifdef HAVE_TERMIOS_H
|
|
||||||
struct termios orig;
|
|
||||||
struct termios noecho;
|
|
||||||
#else
|
|
||||||
# ifdef HAVE_TERMIO_H
|
|
||||||
struct termio orig;
|
|
||||||
struct termio noecho;
|
|
||||||
# else
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
sigint = signal(SIGINT, SIG_IGN);
|
|
||||||
#ifdef SIGTSTP
|
|
||||||
sigtstp = signal(SIGTSTP, SIG_IGN);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
infp=fopen("/dev/tty", "r");
|
|
||||||
if( NULL == infp )
|
|
||||||
infp = stdin;
|
|
||||||
else
|
|
||||||
infp_fclose = 1;
|
|
||||||
|
|
||||||
outfp = stderr;
|
|
||||||
|
|
||||||
infd = fileno(infp);
|
|
||||||
outfd = fileno(outfp);
|
|
||||||
|
|
||||||
/* dissable echo */
|
|
||||||
#ifdef HAVE_TERMIOS_H
|
|
||||||
tcgetattr(outfd, &orig);
|
|
||||||
|
|
||||||
noecho = orig;
|
|
||||||
noecho.c_lflag &= ~ECHO;
|
|
||||||
tcsetattr(outfd, TCSANOW, &noecho);
|
|
||||||
#else
|
|
||||||
# ifdef HAVE_TERMIO_H
|
|
||||||
ioctl(outfd, TCGETA, &orig);
|
|
||||||
noecho = orig;
|
|
||||||
noecho.c_lflag &= ~ECHO;
|
|
||||||
ioctl(outfd, TCSETA, &noecho);
|
|
||||||
# else
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
fputs(prompt, outfp);
|
|
||||||
fflush(outfp);
|
|
||||||
|
|
||||||
bytes_read=read(infd, buffer, buflen);
|
|
||||||
buffer[bytes_read > 0 ? (bytes_read -1) : 0] = '\0';
|
|
||||||
|
|
||||||
/* print a new line if needed */
|
|
||||||
#ifdef HAVE_TERMIOS_H
|
|
||||||
fputs("\n", outfp);
|
|
||||||
#else
|
|
||||||
# ifdef HAVE_TERMIO_H
|
|
||||||
fputs("\n", outfp);
|
|
||||||
# else
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* reset term charectaristics, use TCSAFLUSH incase the
|
|
||||||
* user types more than buflen
|
|
||||||
*/
|
|
||||||
#ifdef HAVE_TERMIOS_H
|
|
||||||
tcsetattr(outfd, TCSAFLUSH, &orig);
|
|
||||||
#else
|
|
||||||
# ifdef HAVE_TERMIO_H
|
|
||||||
ioctl(outfd, TCSETA, &orig);
|
|
||||||
# else
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
signal(SIGINT, sigint);
|
|
||||||
#ifdef SIGTSTP
|
|
||||||
signal(SIGTSTP, sigtstp);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(infp_fclose)
|
|
||||||
fclose(infp);
|
|
||||||
|
|
||||||
return buffer; /* we always return success */
|
|
||||||
}
|
|
||||||
#endif /* VMS */
|
#endif /* VMS */
|
||||||
#else /* WIN32 */
|
|
||||||
#include <stdio.h>
|
#ifdef WIN32
|
||||||
|
/* Windows implementation */
|
||||||
#include <conio.h>
|
#include <conio.h>
|
||||||
char *getpass_r(const char *prompt, char *buffer, size_t buflen)
|
char *getpass_r(const char *prompt, char *buffer, size_t buflen)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
printf("%s", prompt);
|
fputs(prompt, stderr);
|
||||||
|
|
||||||
for(i=0; i<buflen; i++) {
|
for(i=0; i<buflen; i++) {
|
||||||
buffer[i] = getch();
|
buffer[i] = getch();
|
||||||
@ -230,15 +133,98 @@ char *getpass_r(const char *prompt, char *buffer, size_t buflen)
|
|||||||
|
|
||||||
return buffer; /* we always return success */
|
return buffer; /* we always return success */
|
||||||
}
|
}
|
||||||
|
#define DONE
|
||||||
|
#endif /* WIN32 */
|
||||||
|
|
||||||
|
#ifndef DONE /* not previously provided */
|
||||||
|
|
||||||
|
#ifdef HAVE_TERMIOS_H
|
||||||
|
#define struct_term struct termios
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_TERMIO_H
|
||||||
|
#define struct_term struct termio
|
||||||
|
#else
|
||||||
|
#undef struct_term
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* ifndef HAVE_GETPASS_R */
|
static bool ttyecho(bool enable, int fd)
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* for consistensy, here's the old-style function: */
|
|
||||||
char *getpass(const char *prompt)
|
|
||||||
{
|
{
|
||||||
static char buf[256];
|
#ifdef struct_term
|
||||||
return getpass_r(prompt, buf, sizeof(buf));
|
static struct_term withecho;
|
||||||
}
|
static struct_term noecho;
|
||||||
#endif
|
#endif
|
||||||
|
if(!enable) {
|
||||||
|
/* dissable echo by extracting the current 'withecho' mode and remove the
|
||||||
|
ECHO bit and set back the struct */
|
||||||
|
#ifdef HAVE_TERMIOS_H
|
||||||
|
tcgetattr(fd, &withecho);
|
||||||
|
noecho = withecho;
|
||||||
|
noecho.c_lflag &= ~ECHO;
|
||||||
|
tcsetattr(fd, TCSANOW, &noecho);
|
||||||
|
#else /* HAVE_TERMIOS_H */
|
||||||
|
#ifdef HAVE_TERMIO_H
|
||||||
|
ioctl(fd, TCGETA, &withecho);
|
||||||
|
noecho = withecho;
|
||||||
|
noecho.c_lflag &= ~ECHO;
|
||||||
|
ioctl(fd, TCSETA, &noecho);
|
||||||
|
#else /* HAVE_TERMIO_H */
|
||||||
|
/* neither HAVE_TERMIO_H nor HAVE_TERMIOS_H, we can't disable echo! */
|
||||||
|
(void)fd; /* prevent compiler warning on unused variable */
|
||||||
|
return FALSE; /* not disabled */
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
return TRUE; /* disabled */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* re-enable echo, assumes we disabled it before (and set the structs we
|
||||||
|
now use to reset the terminal status) */
|
||||||
|
#ifdef HAVE_TERMIOS_H
|
||||||
|
tcsetattr(fd, TCSAFLUSH, &withecho);
|
||||||
|
#else /* HAVE_TERMIOS_H */
|
||||||
|
#ifdef HAVE_TERMIO_H
|
||||||
|
ioctl(fd, TCSETA, &withecho);
|
||||||
|
#else
|
||||||
|
/* neither HAVE_TERMIO_H nor HAVE_TERMIOS_H */
|
||||||
|
return FALSE; /* not enabled */
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
return TRUE; /* enabled */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char *getpass_r(const char *prompt, /* prompt to display */
|
||||||
|
char *password, /* buffer to store password in */
|
||||||
|
size_t buflen) /* size of buffer to store password in */
|
||||||
|
{
|
||||||
|
ssize_t nread;
|
||||||
|
bool disabled;
|
||||||
|
int fd=open("/dev/tty", O_RDONLY);
|
||||||
|
if(-1 == fd)
|
||||||
|
fd = 1; /* use stdin if the tty couldn't be used */
|
||||||
|
|
||||||
|
disabled = ttyecho(FALSE, fd); /* disable terminal echo */
|
||||||
|
|
||||||
|
fputs(prompt, stderr);
|
||||||
|
nread=read(fd, password, buflen);
|
||||||
|
if(nread > 0)
|
||||||
|
password[--nread]=0; /* zero terminate where enter is stored */
|
||||||
|
else
|
||||||
|
password[0]=0; /* got nothing */
|
||||||
|
|
||||||
|
if(disabled) {
|
||||||
|
/* if echo actually was disabled, add a newline */
|
||||||
|
fputs("\n", stderr);
|
||||||
|
ttyecho(TRUE, fd); /* enable echo */
|
||||||
|
}
|
||||||
|
|
||||||
|
if(1 != fd)
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
return password; /* return pointer to buffer */
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* DONE */
|
||||||
|
|
||||||
|
#endif /* HAVE_GETPASS */
|
||||||
|
#endif /* HAVE_GETPASS_R */
|
||||||
|
@ -49,7 +49,7 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CURLDEBUG
|
#if defined(CURLDEBUG) && defined(CURLTOOLDEBUG)
|
||||||
/* This is an ugly hack for CURLDEBUG conditions only. We need to include
|
/* This is an ugly hack for CURLDEBUG conditions only. We need to include
|
||||||
the file here, since it might set the _FILE_OFFSET_BITS define, which must
|
the file here, since it might set the _FILE_OFFSET_BITS define, which must
|
||||||
be set BEFORE all normal system headers. */
|
be set BEFORE all normal system headers. */
|
||||||
|
Loading…
Reference in New Issue
Block a user