Commit cadcc121 authored by Daniel Stenberg's avatar Daniel Stenberg
Browse files

Added support for password prompting if only used name is given on the

command line.
parent 22adcb9c
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -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
+15 −0
Original line number Diff line number Diff line
@@ -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

src/getpass.c

0 → 100644
+224 −0
Original line number Diff line number Diff line
/* ============================================================================
 * 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

src/getpass.h

0 → 100644
+35 −0
Original line number Diff line number Diff line
#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
+28 −0
Original line number Diff line number Diff line
@@ -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 */