From cadcc12169dc6e57362fcdb0dad763a237c5efc5 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 16 Oct 2003 14:09:39 +0000 Subject: Added support for password prompting if only used name is given on the command line. --- src/Makefile.am | 3 +- src/config.h.in | 15 ++++ src/getpass.c | 224 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/getpass.h | 35 +++++++++ src/main.c | 28 +++++++ 5 files changed, 304 insertions(+), 1 deletion(-) create mode 100644 src/getpass.c create mode 100644 src/getpass.h (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 42e776080..da9c51b2c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -24,7 +24,8 @@ endif curl_SOURCES = main.c hugehelp.c urlglob.c writeout.c setup.h \ config-win32.h config-mac.h config-vms.h config-riscos.h \ - urlglob.h version.h writeout.h writeenv.c writeenv.h + urlglob.h version.h writeout.h writeenv.c writeenv.h \ + getpass.c getpass.h curl_LDADD = ../lib/libcurl.la curl_DEPENDENCIES = ../lib/libcurl.la diff --git a/src/config.h.in b/src/config.h.in index c1589b5d5..4720a1e7b 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -49,3 +49,18 @@ /* Define for large files, on AIX-style hosts. */ #undef _LARGE_FILES + +/* Define to 1 if you have the `getpass_r' function. */ +#undef HAVE_GETPASS_R + +/* Define to 1 if you have the `tcgetattr' function. */ +#undef HAVE_TCGETATTR + +/* Define to 1 if you have the `tcsetattr' function. */ +#undef HAVE_TCSETATTR + +/* Define to 1 if you have the header file. */ +#undef HAVE_TERMIOS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_TERMIO_H diff --git a/src/getpass.c b/src/getpass.c new file mode 100644 index 000000000..225f7f04e --- /dev/null +++ b/src/getpass.c @@ -0,0 +1,224 @@ +/* ============================================================================ + * Copyright (C) 1998 - 2002, Daniel Stenberg, , et al. + * + * Redistribution and use are freely permitted provided that: + * + * 1) This header remain in tact. + * 2) The prototypes for getpass and getpass_r are not changed from: + * char *getpass(const char *prompt) + * 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, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * 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$ + * + * 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 + * + * Contributor(s): + * Daniel Stenberg + */ + +#include "setup.h" /* setup.h is required for read() prototype */ + +#ifndef HAVE_GETPASS_R + +#ifndef WIN32 +#ifdef VMS +#include +#include +#include descrip +#include starlet +#include iodef +#include iosbdef +char *getpass_r(const char *prompt, char *buffer, size_t buflen) +{ + long sts; + short chan; + struct _iosb iosb; + $DESCRIPTOR(ttdesc, "TT"); + + buffer[0]='\0'; + if ((sts = sys$assign(&ttdesc, &chan,0,0)) & 1) { + if (((sts = sys$qiow(0, chan, IO$_READPROMPT | IO$M_NOECHO, &iosb, 0, 0, buffer, buflen, 0, 0, prompt, strlen(prompt))) & 1) && (iosb.iosb$w_status&1)) { + buffer[iosb.iosb$w_bcnt] = '\0'; + } + sts = sys$dassgn(chan); + } + return buffer; /* we always return success */ +} +#else /* VMS */ +#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 +#endif +#include +#include +#ifdef HAVE_TERMIOS_H +# include +#else +# ifdef HAVE_TERMIO_H +# include +# else +# endif +#endif + +/* The last #include file should be: */ +#ifdef CURLDEBUG +#include "../lib/memdebug.h" +#endif + +char *getpass_r(const char *prompt, char *buffer, size_t buflen) +{ + FILE *infp; + char infp_fclose = 0; + FILE *outfp; + RETSIGTYPE (*sigint)(); +#ifdef SIGTSTP + RETSIGTYPE (*sigtstp)(); +#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 */ +#else /* WIN32 */ +#include +#include +char *getpass_r(const char *prompt, char *buffer, int buflen) +{ + int i; + printf("%s", prompt); + + for(i=0; i, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * $Id$ + ***************************************************************************/ +#ifndef HAVE_GETPASS_R +/* If there's a system-provided function named like this, we trust it is + also found in one of the standard headers. */ + +/* + * Returning NULL will abort the continued operation! + */ +char* getpass_r(const char *prompt, char* buffer, size_t buflen ); +#endif + +#endif diff --git a/src/main.c b/src/main.c index 9015362c3..4165d2a3b 100644 --- a/src/main.c +++ b/src/main.c @@ -40,6 +40,7 @@ #include "urlglob.h" #include "writeout.h" +#include "getpass.h" #ifdef USE_ENVIRONMENT #include "writeenv.h" #endif @@ -1050,6 +1051,31 @@ static void cleanarg(char *str) #endif } +static void checkpasswd(const char *prompt, char **userpwd) +{ + char *ptr = strchr(*userpwd, ':'); + if(!ptr) { + /* no password present, prompt for one */ + char passwd[256]=""; + int passwdlen; + int userlen = strlen(*userpwd); + char *ptr; + + getpass_r(prompt, passwd, sizeof(passwd)); + passwdlen = strlen(passwd); + + ptr = realloc(*userpwd, + passwdlen + 1 + /* an extra for the colon */ + userlen + 1); /* an extra for the zero */ + + if(ptr) { + ptr[userlen]=':'; + memcpy(&ptr[userlen+1], passwd, passwdlen+1); + *userpwd = ptr; + } + } +} + static ParameterError getparameter(char *flag, /* f or -long-flag */ char *nextarg, /* NULL if unset */ bool *usedarg, /* set to TRUE if the arg @@ -1808,11 +1834,13 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */ /* user:password */ GetStr(&config->userpwd, nextarg); cleanarg(nextarg); + checkpasswd("Enter host password:", &config->userpwd); break; case 'U': /* Proxy user:password */ GetStr(&config->proxyuserpwd, nextarg); cleanarg(nextarg); + checkpasswd("Enter proxy password:", &config->proxyuserpwd); break; case 'v': config->conf ^= CONF_VERBOSE; /* talk a lot */ -- cgit v1.2.3