After finally managing to accidentally paste a URL with a password in it, I got annoyed enough to work on this. :)
This adds cmd:password-display, with three values: show (do nothing), mask (change passwords to "XXXX"), and hide (don't show the presence of a password at all). The default value is "mask". ("yes" is an alias for "show", and "no" is an alias for "mask".) The hard part is the cmdline output; since it's displayed unparsed, it's nearly impossible to hide passwords there. This is the same problem as putting passwords on a shell commandline: the best solution is to not do it. (I'm thinking about making it so usernames and passwords in bookmarks can be used to complete urls on the commandline.) CopyJob.cc, CopyJob.h: add dispname, use it for status outputs instead of name. Add Reconfig() to update this. url.cc, url.h: add cmd:password-display, use it in ParsedURL::Combine when told to. pgetJob.cc: use dispname for display. Maybe this could be used for bookmark hiding, instead of the special case parser; I didn't investigate this. -- Glenn Maynard
Index: doc/lftp.1 =================================================================== RCS file: /home/lav/cvsroot/lftp/doc/lftp.1,v retrieving revision 1.77 diff -u -r1.77 lftp.1 --- doc/lftp.1 2002/08/02 08:13:06 1.77 +++ doc/lftp.1 2002/08/13 19:49:01 @@ -737,6 +737,25 @@ considered as `long' and a beep is done before next prompt. 0 means off. .TP +.BR cmd:password-display \ (string) +Affects display of passwords in URLs. +Warning: this only affects passwords in parsed URLs. Passwords in other +places, such as on commandlines, are unaffected. +.RS +.PD 0 +.TP +.B show +Passwords are shown. +.TP +.B mask +Passwords are replaced with "XXXX". +.TP +.B hide +Passwords are removed entirely. +.RE +.PD + +.TP .BR cmd:ls-default \ (string) default ls argument .TP Index: src/CopyJob.cc =================================================================== RCS file: /home/lav/cvsroot/lftp/src/CopyJob.cc,v retrieving revision 1.28 diff -u -r1.28 CopyJob.cc --- src/CopyJob.cc 2002/07/31 11:28:00 1.28 +++ src/CopyJob.cc 2002/08/13 19:49:01 @@ -25,6 +25,7 @@ #include "ArgV.h" #include "plural.h" #include "misc.h" +#include "url.h" int CopyJob::Do() { @@ -73,8 +74,8 @@ const char *CopyJob::SqueezeName(int w, bool base) { if(base) - return squeeze_file_name(basename_ptr(name),w); - return squeeze_file_name(name,w); + return squeeze_file_name(basename_ptr(GetDispName()),w); + return squeeze_file_name(GetDispName(),w); } // xgettext:c-format @@ -118,11 +119,18 @@ return; printf("%s",prefix); - const char *name=GetName(); + const char *name=GetDispName(); printf(COPY_STATUS); printf("\n"); } +void CopyJob::Reconfig(const char *name) +{ + if(name == 0 || !strcmp(name, "cmd:password-display")) { + SetDispName(); + } +} + int CopyJob::AcceptSig(int sig) { if(c==0 || GetProcGroup()==0) @@ -137,21 +145,36 @@ return MOVED; } +void CopyJob::SetDispName() +{ + xfree(dispname); + dispname=0; + + ParsedURL url(name,true); + if(url.proto) + dispname = url.Combine(0,true, NULL); + else + dispname = xstrdup(name); +} + CopyJob::CopyJob(FileCopy *c1,const char *name1,const char *op1) { c=c1; + dispname=0; name=xstrdup(name1); op=xstrdup(op1); done=false; no_status=false; no_status_on_write=false; clear_status_on_write=false; + SetDispName(); } CopyJob::~CopyJob() { Delete(c); xfree(name); + xfree(dispname); xfree(op); } Index: src/CopyJob.h =================================================================== RCS file: /home/lav/cvsroot/lftp/src/CopyJob.h,v retrieving revision 1.17 diff -u -r1.17 CopyJob.h --- src/CopyJob.h 2002/07/31 11:28:00 1.17 +++ src/CopyJob.h 2002/08/13 19:49:01 @@ -32,11 +32,14 @@ FileCopy *c; bool done; char *name; // file name + char *dispname; // displayed file name char *op; // command name bool no_status; bool no_status_on_write; bool clear_status_on_write; + void SetDispName(); + public: CopyJob(FileCopy *c1,const char *n,const char *op1); ~CopyJob(); @@ -78,8 +81,10 @@ const char *Status(const StatusLine *s,bool base=false); void ShowRunStatus(StatusLine *s); void PrintStatus(int,const char *); + void Reconfig(const char *name=0); - const char *GetName() { return name; } + const char *GetName() const { return name; } + const char *GetDispName() const { return dispname; } const char *SqueezeName(int w, bool base=false); static CopyJob *NewGet(FileAccess *f,const char *src,const char *dst); Index: src/pgetJob.cc =================================================================== RCS file: /home/lav/cvsroot/lftp/src/pgetJob.cc,v retrieving revision 1.31 diff -u -r1.31 pgetJob.cc --- src/pgetJob.cc 2002/07/31 14:39:52 1.31 +++ src/pgetJob.cc 2002/08/13 19:49:01 @@ -223,7 +223,7 @@ SessionJob::PrintStatus(verbose,prefix); printf("\t"); - const char *name=cp->GetName(); + const char *name=cp->GetDispName(); off_t size=cp->GetSize(); printf(PGET_STATUS); printf("\n"); Index: src/url.cc =================================================================== RCS file: /home/lav/cvsroot/lftp/src/url.cc,v retrieving revision 1.26 diff -u -r1.26 url.cc --- src/url.cc 2002/08/01 11:28:26 1.26 +++ src/url.cc 2002/08/13 19:49:02 @@ -27,7 +27,31 @@ #include "ascii_ctype.h" #include "ConnectionSlot.h" #include "misc.h" +#include "ResMgr.h" +static const char *ValidatePasswdDisp(char **value) +{ + char *v=*value; + const char *newval=0; + + if(!strcasecmp(v, "yes")) newval = "show"; + else if(!strcasecmp(v, "no")) newval = "mask"; + else if(!strcasecmp(v, "hide")) newval = "hide"; + else if(!strcasecmp(v, "mask")) newval = "mask"; + else if(!strcasecmp(v, "show")) newval = "show"; + else return _("invalid value"); + + if(strcmp(v,newval)) + { + xfree(v); + *value=xstrdup(newval); + } + + return NULL; +} + +ResDecl hide_password("cmd:password-display", "mask", ValidatePasswdDisp,0); + /* URL -> [PROTO://]CONNECT[[:]/PATH] CONNECT -> [USER[:PASS]@]HOST[:PORT] @@ -290,7 +314,7 @@ return 0; } -char *ParsedURL::Combine(const char *home,bool use_rfc1738) +char *ParsedURL::Combine(const char *home,bool use_rfc1738,const char *hide_passwords) { int len=1; if(proto) @@ -324,8 +348,16 @@ url::encode_string(user,url+strlen(url),URL_USER_UNSAFE); if(pass) { - strcat(url,":"); - url::encode_string(pass,url+strlen(url),URL_PASS_UNSAFE); + const char *hide = hide_passwords; + if(hide == NULL) + hide = hide_password.Query(0); + + if(!hide || strcmp(hide_password.Query(0), "hide")) + strcat(url,":"); + if(!hide || !strcmp(hide, "show")) + url::encode_string(pass,url+strlen(url),URL_PASS_UNSAFE); + if(!hide || !strcmp(hide, "mask")) + strcat(url+strlen(url), "XXXX"); } strcat(url,"@"); } Index: src/url.h =================================================================== RCS file: /home/lav/cvsroot/lftp/src/url.h,v retrieving revision 1.13 diff -u -r1.13 url.h --- src/url.h 2002/07/31 14:40:03 1.13 +++ src/url.h 2002/08/13 19:49:02 @@ -44,7 +44,7 @@ } // returns allocated memory - char *Combine(const char *home=0,bool use_rfc1738=true); + char *Combine(const char *home=0,bool use_rfc1738=true,const char +*hide_passwords="show"); }; # define URL_UNSAFE " <>\"%{}|\\^[]`"