Discussion:
[freetds] Proposed patch to datacopy to allow passwords to be read from stdin
PublicMailbox
2012-08-16 15:36:21 UTC
Permalink
The patch below would permit the datacopy utility to use a dash for the password in the source or destination server parameter to mean "read from standard in". For example:

datacopy -Smyserver/myusername/-/mydatabase/mytable ...

Upon finding a dash for the password, datacopy would prompt for the password and read it in.

Using a dash for a parameter to specify "read from stdin" is a typical style for many Unix/Linux utilities.

This feature is needed to prevent the security violation of putting a password on the command line (which makes it visible to ps -f in Unix/Linux). For batch (non-interactive)
jobs in an enterprise environment, this is a mandatory requirement. Using kerberos might be better, but that's a much harder change.

Ben Slade
diff -u datacopy.c.orig datacopy.c
--- datacopy.c.orig 2011-05-16 04:51:40.000000000 -0400
+++ datacopy.c 2012-08-16 11:18:55.583213000 -0400
@@ -246,6 +246,10 @@
if (!tok)
return FALSE;
pdata->spass = strdup(tok);
+ if( strcmp(pdata->spass,"-") == 0 ) {
+ printf("Enter Source Password : ");
+ pdata->spass = gets_alloc();
+ }

tok = strtok(NULL, "/");
if (!tok)
@@ -277,6 +281,10 @@
if (!tok)
return FALSE;
pdata->dpass = strdup(tok);
+ if( strcmp(pdata->dpass,"-") == 0 ) {
+ printf("Enter Destination Password : ");
+ pdata->dpass = gets_alloc();
+ }

tok = strtok(NULL, "/");
if (!tok)
James K. Lowden
2012-08-18 19:36:38 UTC
Permalink
On Thu, 16 Aug 2012 11:36:21 -0400
Post by PublicMailbox
Upon finding a dash for the password, datacopy would prompt for the
password and read it in.
Using a dash for a parameter to specify "read from stdin" is a
typical style for many Unix/Linux utilities.
A dash is commonly recognized as an alias for standard input, but it's
rarely used for passwords. And nowadays most systems
support /dev/stdin, freeing the utility from assigning special meaning
to '-'.

Why not interpolate instead? To read a password on stdin, something
has to produce it on stdout. Just insert it at the right place using
`` or $().

Before we fully supported Kerberos, I kept passwords in ${HOME}/.netrc,
a file traditionally used by many ftp utilities and some others,
including fetchmail and wget. For a description of the format, see e.g.
http://man.cx/netrc (4).

I had a script such as

#! /bin/sh
awk "\$2 == \"$1\" {print \$6}" ~/.netrc

called "getpass". Now the command:

datacopy -S$S/$U/$(getpass $S)/$D/$T ...

does the job.
Post by PublicMailbox
Using kerberos might be better, but that's a much harder change.
Not that much harder, and worthwhile if your environment supports it.
Look at what the other db-lib utilities do.

HTH.

--jkl
Stuart Henderson
2012-08-23 01:16:24 UTC
Permalink
Post by James K. Lowden
I had a script such as
#! /bin/sh
awk "\$2 == \"$1\" {print \$6}" ~/.netrc
datacopy -S$S/$U/$(getpass $S)/$D/$T ...
does the job.
This still shows in the command line, though.
Frediano Ziglio
2012-08-23 14:38:38 UTC
Permalink
Post by Stuart Henderson
Post by James K. Lowden
I had a script such as
#! /bin/sh
awk "\$2 == \"$1\" {print \$6}" ~/.netrc
datacopy -S$S/$U/$(getpass $S)/$D/$T ...
does the job.
This still shows in the command line, though.
I agree passing a password on command line is a security risk.

If I remember many of our tools ask for password if argument is
omitted. We use a readpassphrase function to read the password in a
portable and threadsafe way. In this case we cannot omit the password
and perhaps empty password is more common than a single dash.

Frediano
James K. Lowden
2012-08-24 18:06:28 UTC
Permalink
On Thu, 23 Aug 2012 01:16:24 +0000 (UTC)
Post by Stuart Henderson
Post by James K. Lowden
datacopy -S$S/$U/$(getpass $S)/$D/$T ...
does the job.
This still shows in the command line, though.
No, what shows on the command line is "$(getpass $S)". That's what you
type in; that's what shows in ps(1). That's what will be in any log of
the script.

We seem to be talking past each other. What are you referring to?

--jkl
Frediano Ziglio
2012-09-07 18:34:51 UTC
Permalink
Post by James K. Lowden
On Thu, 23 Aug 2012 01:16:24 +0000 (UTC)
Post by Stuart Henderson
Post by James K. Lowden
datacopy -S$S/$U/$(getpass $S)/$D/$T ...
does the job.
This still shows in the command line, though.
No, what shows on the command line is "$(getpass $S)". That's what you
type in; that's what shows in ps(1). That's what will be in any log of
the script.
We seem to be talking past each other. What are you referring to?
Hi,
James, the shell expand the command so in ps you see the password. Perhaps environment is more safe and hard to read but I think pipe or external file are better.

Frediano
James K. Lowden
2012-09-09 18:20:42 UTC
Permalink
On Fri, 7 Sep 2012 19:34:51 +0100
Il giorno 24/ago/2012, alle ore 19:06, "James K. Lowden"
Post by James K. Lowden
On Thu, 23 Aug 2012 01:16:24 +0000 (UTC)
Post by Stuart Henderson
Post by James K. Lowden
datacopy -S$S/$U/$(getpass $S)/$D/$T ...
does the job.
This still shows in the command line, though.
No, what shows on the command line is "$(getpass $S)".
James, the shell expand the command so in ps you see the password.
Perhaps environment is more safe and hard to read but I think pipe or
external file are better.
Ah, I see. Thanks for the clarification. Still, I reject the patch
because, no offense intended, it's the wrong approach.

Using ps(1) you can seen the expanded result of my
$(getpass $S). For that to be possible, though, you need to be either

1) the user (running under the same effective uid)
or
2) root

A local file is subject to the same inspection as the process's
environment. It is thus no better or worse than my solution.

Granted, it's possible to get the password from another machine
instead using, say, ssh. Granted also Mr. Slade's patch is less work
than adding Kerberos to datacopy. IMO it is still too much work for
too little benefit, because very few users will bother to feed standard
input from an off-machine resource.

I added Kerberos support to the FreeTDS utilities once support for
Kerberos and SSPI were fully integrated into the libraries. The only
one I didn't touch was datacopy, mosty because I didn't use it. From
that experience I know it's not hard to do.

I would be delighted to see a patch bringing Kerberos to datacopy. For
extra credit, change it to use getopt(3) too.

--jkl
Frediano Ziglio
2012-09-09 20:45:16 UTC
Permalink
Post by James K. Lowden
On Fri, 7 Sep 2012 19:34:51 +0100
Il giorno 24/ago/2012, alle ore 19:06, "James K. Lowden"
Post by James K. Lowden
On Thu, 23 Aug 2012 01:16:24 +0000 (UTC)
Post by Stuart Henderson
Post by James K. Lowden
datacopy -S$S/$U/$(getpass $S)/$D/$T ...
does the job.
This still shows in the command line, though.
No, what shows on the command line is "$(getpass $S)".
James, the shell expand the command so in ps you see the password.
Perhaps environment is more safe and hard to read but I think pipe or
external file are better.
Ah, I see. Thanks for the clarification. Still, I reject the patch
because, no offense intended, it's the wrong approach.
Using ps(1) you can seen the expanded result of my
$(getpass $S). For that to be possible, though, you need to be either
1) the user (running under the same effective uid)
or
2) root
A local file is subject to the same inspection as the process's
environment. It is thus no better or worse than my solution.
At least Linux and HP-UX does not require such things to get access to
command line. Environment perhaps required it but ps returns the
expanded command line
Post by James K. Lowden
Granted, it's possible to get the password from another machine
instead using, say, ssh. Granted also Mr. Slade's patch is less work
than adding Kerberos to datacopy. IMO it is still too much work for
too little benefit, because very few users will bother to feed standard
input from an off-machine resource.
I added Kerberos support to the FreeTDS utilities once support for
Kerberos and SSPI were fully integrated into the libraries. The only
one I didn't touch was datacopy, mosty because I didn't use it. From
that experience I know it's not hard to do.
I would be delighted to see a patch bringing Kerberos to datacopy. For
extra credit, change it to use getopt(3) too.
--jkl
I vote for getopt too!

However I think that all tools support reading from standard input too
so the patch would only align datacopy to other tools.

Frediano
James K. Lowden
2012-09-10 02:49:07 UTC
Permalink
On Sun, 9 Sep 2012 21:45:16 +0100
Post by Frediano Ziglio
Post by James K. Lowden
A local file is subject to the same inspection as the process's
environment. It is thus no better or worse than my solution.
At least Linux and HP-UX does not require such things to get access to
command line. Environment perhaps required it but ps returns the
expanded command line
I see. Yes, that makes sense. The only command line ps(1) could show
would be the one passed to the kernel after the shell finished
processing any metacharacters.
Post by Frediano Ziglio
I vote for getopt too!
:-)
Post by Frediano Ziglio
However I think that all tools support reading from standard input too
so the patch would only align datacopy to other tools.
OK. I withdraw my objection. Let's apply it. I continue to hope
someone will add Kerberos to datacopy, too.

--jkl
Frediano Ziglio
2012-09-10 17:19:26 UTC
Permalink
Post by James K. Lowden
On Sun, 9 Sep 2012 21:45:16 +0100
Post by Frediano Ziglio
Post by James K. Lowden
A local file is subject to the same inspection as the process's
environment. It is thus no better or worse than my solution.
At least Linux and HP-UX does not require such things to get access to
command line. Environment perhaps required it but ps returns the
expanded command line
I see. Yes, that makes sense. The only command line ps(1) could show
would be the one passed to the kernel after the shell finished
processing any metacharacters.
Post by Frediano Ziglio
I vote for getopt too!
:-)
Post by Frediano Ziglio
However I think that all tools support reading from standard input too
so the patch would only align datacopy to other tools.
OK. I withdraw my objection. Let's apply it. I continue to hope
someone will add Kerberos to datacopy, too.
If I remember just using empty username and password will do so just
replacing strtok with strsep should work. The only problem is that
strsep are not portable but I found this link
http://www.mail-archive.com/notmuch at notmuchmail.org/msg09941.html with
LGPL implementation.

Just add to replacements and use it!

Frediano
James K. Lowden
2012-09-11 03:14:58 UTC
Permalink
On Mon, 10 Sep 2012 18:19:26 +0100
Post by Frediano Ziglio
If I remember just using empty username and password will do so just
replacing strtok with strsep should work.
strtok(3) is standard and OK to use here. Command-line parsing isn't
re-entrant or multithreaded.

--jkl
Frediano Ziglio
2012-09-11 08:21:06 UTC
Permalink
Post by James K. Lowden
On Mon, 10 Sep 2012 18:19:26 +0100
Post by Frediano Ziglio
If I remember just using empty username and password will do so just
replacing strtok with strsep should work.
strtok(3) is standard and OK to use here. Command-line parsing isn't
re-entrant or multithreaded.
Well, you could use strtok_r if you just need re-entrancy and
multihreading. However there is another difference between strtok and
strsep. If you try to split a string like "a//b" with "/" with strtok
you get "a", "b" while with strsep you get "a", "", "b". So passing
server/username/password if username and password are empty (something
like "server//") with strsep you get empty username and password (that
is Kerberos!).

Frediano
Frediano Ziglio
2012-09-16 08:42:44 UTC
Permalink
Post by PublicMailbox
datacopy -Smyserver/myusername/-/mydatabase/mytable ...
Upon finding a dash for the password, datacopy would prompt for the password and read it in.
Using a dash for a parameter to specify "read from stdin" is a typical style for many Unix/Linux utilities.
This feature is needed to prevent the security violation of putting a password on the command line (which makes it visible to ps -f in Unix/Linux). For batch (non-interactive)
jobs in an enterprise environment, this is a mandatory requirement. Using kerberos might be better, but that's a much harder change.
Ben Slade
diff -u datacopy.c.orig datacopy.c
--- datacopy.c.orig 2011-05-16 04:51:40.000000000 -0400
+++ datacopy.c 2012-08-16 11:18:55.583213000 -0400
@@ -246,6 +246,10 @@
if (!tok)
return FALSE;
pdata->spass = strdup(tok);
+ if( strcmp(pdata->spass,"-") == 0 ) {
+ printf("Enter Source Password : ");
+ pdata->spass = gets_alloc();
+ }
tok = strtok(NULL, "/");
if (!tok)
@@ -277,6 +281,10 @@
if (!tok)
return FALSE;
pdata->dpass = strdup(tok);
+ if( strcmp(pdata->dpass,"-") == 0 ) {
+ printf("Enter Destination Password : ");
+ pdata->dpass = gets_alloc();
+ }
tok = strtok(NULL, "/");
if (!tok)
Applied (modified).

https://gitorious.org/freetds/freetds/commit/9dc94619e6772b07932172e751f2d2d6ae5417d0

Current code support Kerberos too (see change
https://gitorious.org/freetds/freetds/commit/a8f2145344f1b9017a9453a2ac29467f5e56d58e)

Frediano

Loading...