Added support for password prompting if only used name is given on the
authorDaniel Stenberg <daniel@haxx.se>
Thu, 16 Oct 2003 14:09:39 +0000 (14:09 +0000)
committerDaniel Stenberg <daniel@haxx.se>
Thu, 16 Oct 2003 14:09:39 +0000 (14:09 +0000)
command line.

src/Makefile.am
src/config.h.in
src/getpass.c [new file with mode: 0644]
src/getpass.h [new file with mode: 0644]
src/main.c

index 42e7760..da9c51b 100644 (file)
@@ -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
index c1589b5..4720a1e 100644 (file)
 
 /* 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 (file)
index 0000000..225f7f0
--- /dev/null
@@ -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 (file)
index 0000000..af24dbc
--- /dev/null
@@ -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
index 9015362..4165d2a 100644 (file)
@@ -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 */