aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2003-10-16 14:09:39 +0000
committerDaniel Stenberg <daniel@haxx.se>2003-10-16 14:09:39 +0000
commitcadcc12169dc6e57362fcdb0dad763a237c5efc5 (patch)
tree8fd45ee9006271a1df48740dd5a81c3a6fb2c204 /src
parent22adcb9cd1d99858f10e55dc140ceb19d382eee5 (diff)
Added support for password prompting if only used name is given on the
command line.
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am3
-rw-r--r--src/config.h.in15
-rw-r--r--src/getpass.c224
-rw-r--r--src/getpass.h35
-rw-r--r--src/main.c28
5 files changed, 304 insertions, 1 deletions
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 <termios.h> header file. */
+#undef HAVE_TERMIOS_H
+
+/* Define to 1 if you have the <termio.h> 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, <daniel@haxx.se>, 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 <amackay@gus.ml.org>
+ *
+ * Contributor(s):
+ * Daniel Stenberg <daniel@haxx.se>
+ */
+
+#include "setup.h" /* setup.h is required for read() prototype */
+
+#ifndef HAVE_GETPASS_R
+
+#ifndef WIN32
+#ifdef VMS
+#include <stdio.h>
+#include <string.h>
+#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 <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: */
+#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 <stdio.h>
+#include <conio.h>
+char *getpass_r(const char *prompt, char *buffer, int buflen)
+{
+ int i;
+ printf("%s", prompt);
+
+ for(i=0; i<buflen; i++) {
+ buffer[i] = getch();
+ if ( buffer[i] == '\r' ) {
+ buffer[i] = 0;
+ break;
+ }
+ }
+ /* if user didn't hit ENTER, terminate buffer */
+ if (i==buflen)
+ buffer[buflen-1]=0;
+
+ return buffer; /* we always return success */
+}
+#endif
+
+#endif /* ifndef HAVE_GETPASS_R */
+
+#if 0
+/* for consistensy, here's the old-style function: */
+char *getpass(const char *prompt)
+{
+ static char buf[256];
+ return getpass_r(prompt, buf, sizeof(buf));
+}
+#endif
diff --git a/src/getpass.h b/src/getpass.h
new file mode 100644
index 000000000..af24dbcac
--- /dev/null
+++ b/src/getpass.h
@@ -0,0 +1,35 @@
+#ifndef __GETPASS_H
+#define __GETPASS_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2003, Daniel Stenberg, <daniel@haxx.se>, 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 */