diff -u -r -N ccvs/NEWS ccvs.1/NEWS --- ccvs/NEWS Tue Jul 9 15:15:32 2002 +++ ccvs.1/NEWS Thu Sep 12 18:19:21 2002 @@ -1,5 +1,11 @@ Changes since 1.11.2: +* When cvs needs a passphrase (e.g. login) it will read it from the current +terminal (console) if is available. If no terminal associated with it, cvs +will attempt to run a program pointed by CVS_ASKPASS variable. This is +particularly useful when calling cvs from X session. (Note that on some machines +it may be necessary to redirect the input from /dev/null to get it working.) + * When waiting for another user's lock, the message timestamps are now in UTC rather than the server's local time. diff -u -r -N ccvs/src/ChangeLog ccvs.1/src/ChangeLog --- ccvs/src/ChangeLog Thu Aug 29 02:00:59 2002 +++ ccvs.1/src/ChangeLog Thu Sep 12 18:46:40 2002 @@ -1,3 +1,8 @@ +2000-09-12 Dmitri Dmitrienko + + * login.c: Add support for 3rd party passphrase asking programs. + * askpass.c: Implement running 3rd party passphrase asking programs. + 2002-08-28 Larry Jones * logmsg.c (do_editor): Fix bug which prevented reusing log messages. diff -u -r -N ccvs/src/Makefile.am ccvs.1/src/Makefile.am --- ccvs/src/Makefile.am Wed May 8 14:39:20 2002 +++ ccvs.1/src/Makefile.am Thu Sep 12 18:36:16 2002 @@ -30,6 +30,7 @@ add.c \ admin.c \ annotate.c \ + askpass.c \ buffer.c \ checkin.c \ checkout.c \ diff -u -r -N ccvs/src/askpass.c ccvs.1/src/askpass.c --- ccvs/src/askpass.c Wed Dec 31 21:00:00 1969 +++ ccvs.1/src/askpass.c Thu Sep 12 19:22:10 2002 @@ -0,0 +1,111 @@ +/* + Allow user to log in using graphical front-end. + written by Dmitri Dmitrienko +*/ + + +#include "cvs.h" +#include "askpass.h" + +#ifdef AUTH_CLIENT_SUPPORT /* This covers the rest of the file. */ + +#ifdef HAVE_GETPASSPHRASE +#define GETPASS getpassphrase +#else +#define GETPASS getpass +#endif + +/* There seems to be very little agreement on which system header + getpass is declared in. With a lot of fancy autoconfiscation, + we could perhaps detect this, but for now we'll just rely on + _CRAY, since Cray is perhaps the only system on which our own + declaration won't work (some Crays declare the 2#$@% thing as + varadic, believe it or not). On Cray, getpass will be declared + in either stdlib.h or unistd.h. */ +#ifndef _CRAY +extern char *GETPASS (); +#endif + + +static char pass_buff[1024]; // don't worry, login() cleans it up + +char *cvs_run_askpass(askpass_prog, pass_prompt) + char *askpass_prog; + char *pass_prompt; +{ + char *argv[3]; + int tofdp, fromfdp; + int len, ret; + int askpass_pid, status; + + argv[0] = askpass_prog; + argv[1] = pass_prompt; + argv[2] = NULL; + if (trace) + { + int i; + + fprintf (stderr, " -> Starting askpass: "); + for (i = 0; argv[i]; i++) + fprintf (stderr, "%s ", argv[i]); + putc ('\n', stderr); + } + askpass_pid = piped_child (argv, &tofdp, &fromfdp); + + if (askpass_pid < 0) { + error (1, errno, "cannot start askpass"); + } + + len = ret = 0; + do { + ret = read(fromfdp, pass_buff + len, sizeof(pass_buff) - 1 - len); + if (ret == -1 && errno == EINTR) + continue; + if (ret <= 0) + break; + len += ret; + } while (len < sizeof(pass_buff) - 1); + pass_buff[len] = '\0'; + + close(fromfdp); + close(tofdp); + + while (waitpid(askpass_pid, &status, 0) < 0) + if (errno != EINTR) + break; + + pass_buff[strcspn(pass_buff, "\r\n")] = '\0'; + return pass_buff; +} + +/* Prompt for a password, and scrambles it. + */ + +char *cvs_ask_pass(cvs_root) + char *cvs_root; +{ + char *tmp, *retval, *askpass_prog; + int ttyfd, use_askpass = 0; + +// test TTY availability + ttyfd = open(_PATH_TTY, O_RDONLY); + if (ttyfd >= 0) + close(ttyfd); + else + use_askpass = 1; + + if (use_askpass) { + askpass_prog = getenv(CVS_ASKPASS_ENV); + if (!askpass_prog) + askpass_prog = _CVS_ASKPASS_DEFAULT; + tmp = cvs_run_askpass(askpass_prog, cvs_root); + } + else { + tmp = GETPASS ("CVS password: "); + } + retval = scramble (tmp); + memset (tmp, 0, strlen (tmp)); + return retval; +} + +#endif diff -u -r -N ccvs/src/askpass.h ccvs.1/src/askpass.h --- ccvs/src/askpass.h Wed Dec 31 21:00:00 1969 +++ ccvs.1/src/askpass.h Thu Sep 12 19:05:46 2002 @@ -0,0 +1,26 @@ +#ifndef _ASKPASS_H +#define _ASKPASS_H + +#ifndef _PATH_TTY +#ifdef HAVE_CYGWIN +# define _PATH_TTY "/dev/tty" +#else +#ifdef WIN32 +# define _PATH_TTY "CONIN$" +#else +# define _PATH_TTY "/dev/tty" +#endif +#endif +#endif + + +#ifndef _CVS_ASKPASS_DEFAULT +#define _CVS_ASKPASS_DEFAULT "cvs-askpass" +#endif + +#define CVS_ASKPASS_ENV "CVS_ASKPASS" + + +extern char *cvs_ask_pass PROTO((char *)); + +#endif diff -u -r -N ccvs/src/login.c ccvs.1/src/login.c --- ccvs/src/login.c Thu May 23 15:13:17 2002 +++ ccvs.1/src/login.c Thu Sep 12 19:10:09 2002 @@ -12,22 +12,7 @@ #ifdef AUTH_CLIENT_SUPPORT /* This covers the rest of the file. */ -#ifdef HAVE_GETPASSPHRASE -#define GETPASS getpassphrase -#else -#define GETPASS getpass -#endif - -/* There seems to be very little agreement on which system header - getpass is declared in. With a lot of fancy autoconfiscation, - we could perhaps detect this, but for now we'll just rely on - _CRAY, since Cray is perhaps the only system on which our own - declaration won't work (some Crays declare the 2#$@% thing as - varadic, believe it or not). On Cray, getpass will be declared - in either stdlib.h or unistd.h. */ -#ifndef _CRAY -extern char *GETPASS (); -#endif +#include "askpass.h" #ifndef CVS_PASSWORD_FILE #define CVS_PASSWORD_FILE ".cvspass" @@ -541,7 +526,7 @@ else { char *tmp; - tmp = GETPASS ("CVS password: "); + tmp = cvs_ask_pass (cvsroot_canonical); /* Must deal with a NULL return value here. I haven't managed to * disconnect the CVS process from the tty and force a NULL return * in sanity.sh, but the Linux version of getpass is documented