public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* Is getpass(3) really obsolete?
@ 2021-10-29 11:15 Alejandro Colomar
  2021-10-29 11:28 ` Alejandro Colomar (man-pages)
  0 siblings, 1 reply; 24+ messages in thread
From: Alejandro Colomar @ 2021-10-29 11:15 UTC (permalink / raw)
  To: Libc-alpha, linux-man

Hi,

As the manual pages says, SUSv2 marked it as LEGACY, and POSIX doesn't 
have it at all.  The manual page goes further and says "This function is 
obsolete. Do not use it." in its first lines.

But, glibc doesn't seem to have deprecated this function at all.  And it 
seems to be the most portable way to get a password, even if it's not in 
POSIX.

BSDs have readpassphrase(3), but glibc doesn't, so unless you recommend 
using readpassphrase(3) from libbsd, or plan to add it to glibc, I think 
getpass(3) should be the recommended function in Linux, and therefore we 
should remove the hard words against it.

As a real example, git(1) uses getpass(3).
<https://github.com/git/git/blob/master/compat/terminal.c>

What are your thoughts?

Thanks,

Alex


-- 
Alejandro Colomar
Linux man-pages comaintainer; https://www.kernel.org/doc/man-pages/
http://www.alejandro-colomar.es/

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Is getpass(3) really obsolete?
  2021-10-29 11:15 Is getpass(3) really obsolete? Alejandro Colomar
@ 2021-10-29 11:28 ` Alejandro Colomar (man-pages)
  2021-10-29 11:40   ` Ævar Arnfjörð Bjarmason
                     ` (3 more replies)
  0 siblings, 4 replies; 24+ messages in thread
From: Alejandro Colomar (man-pages) @ 2021-10-29 11:28 UTC (permalink / raw)
  To: Libc-alpha, linux-man; +Cc: git, tech

[Add a few CCs, since I mentioned them.]

On 10/29/21 13:15, Alejandro Colomar wrote:
> Hi,
> 
> As the manual pages says, SUSv2 marked it as LEGACY, and POSIX doesn't 
> have it at all.  The manual page goes further and says "This function is 
> obsolete. Do not use it." in its first lines.
> 
> But, glibc doesn't seem to have deprecated this function at all.  And it 
> seems to be the most portable way to get a password, even if it's not in 
> POSIX.
> 
> BSDs have readpassphrase(3), but glibc doesn't, so unless you recommend 

OpenBSD also marks getpass(3) as obsolete and recommends readpassphrase(3):
<https://man.openbsd.org/getpass>

> using readpassphrase(3) from libbsd, or plan to add it to glibc, I think 
> getpass(3) should be the recommended function in Linux, and therefore we 
> should remove the hard words against it.
> 
> As a real example, git(1) uses getpass(3).
> <https://github.com/git/git/blob/master/compat/terminal.c>
> 
> What are your thoughts?
> 
> Thanks,
> 
> Alex
> 
> 

-- 
Alejandro Colomar
Linux man-pages comaintainer; https://www.kernel.org/doc/man-pages/
http://www.alejandro-colomar.es/

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Is getpass(3) really obsolete?
  2021-10-29 11:28 ` Alejandro Colomar (man-pages)
@ 2021-10-29 11:40   ` Ævar Arnfjörð Bjarmason
  2021-10-29 12:11     ` Alejandro Colomar (man-pages)
  2021-10-29 12:10   ` rsbecker
                     ` (2 subsequent siblings)
  3 siblings, 1 reply; 24+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-10-29 11:40 UTC (permalink / raw)
  To: Alejandro Colomar (man-pages)
  Cc: Libc-alpha, linux-man, git, tech, Benoit Lecocq, Klemens Nanni


On Fri, Oct 29 2021, Alejandro Colomar (man-pages) wrote:

> [Add a few CCs, since I mentioned them.]

[I'm not sure what the full context of this thread is, but just replying
from the POV of git@ being CC'd on this]

> On 10/29/21 13:15, Alejandro Colomar wrote:
>> Hi,
>> As the manual pages says, SUSv2 marked it as LEGACY, and POSIX
>> doesn't have it at all.  The manual page goes further and says "This
>> function is obsolete. Do not use it." in its first lines.
>> But, glibc doesn't seem to have deprecated this function at all. 
>> And it seems to be the most portable way to get a password, even if
>> it's not in POSIX.
>> BSDs have readpassphrase(3), but glibc doesn't, so unless you
>> recommend 
>
> OpenBSD also marks getpass(3) as obsolete and recommends readpassphrase(3):
> <https://man.openbsd.org/getpass>

Simply not being familiar with that case: Is that suggestive of
getpass(3) being bad to use in general, or a case where OpenBSD's
deprecation of it makes sense holistically on that OS, but not
necessarily elsewhere?

Just skimming the linked man pages it looks like OpenBSD might have
deprecated it at least partly due to getpass() accepting a password on
stdin.

Even within OpenBSD I wonder what that case means for software such as
git. I.e. is it better to be portable and accept the same behavior on
OpenBSD as elsewhere, or conform more closely to platform-specific
conventions.

I haven't looked closely out our getpass() integration, maybe that's a
moot point either way.

>> using readpassphrase(3) from libbsd, or plan to add it to glibc, I
>> think getpass(3) should be the recommended function in Linux, and
>> therefore we should remove the hard words against it.
>> As a real example, git(1) uses getpass(3).
>> <https://github.com/git/git/blob/master/compat/terminal.c>
>> What are your thoughts?
>> Thanks,
>> Alex
>> 

Just while we've got some OpenBSD people CC'd (added the devel/git
maintainers). I occasionally test git on OpenBSD myself (on the GCC
farm), and we've got a few broken tests on the platform.

Looking at the ports source there's at least a couple of OpenBSD
portability patches in there that would make sense to
upstream.

So if that's easy for you or you're willing to submit them upstream we'd
be happy to take them. Usually the only reason we haven't fixed things
like that already is because nobody told us, and we're not actively
looking into the local patches local packagers apply.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* RE: Is getpass(3) really obsolete?
  2021-10-29 11:28 ` Alejandro Colomar (man-pages)
  2021-10-29 11:40   ` Ævar Arnfjörð Bjarmason
@ 2021-10-29 12:10   ` rsbecker
  2021-10-29 13:55     ` Eugene Syromyatnikov
  2021-10-29 13:55     ` Theo de Raadt
  2021-10-29 15:27   ` [PATCH] getpass.3: SYNOPSIS: Mark getpass() as [[deprecated]] Alejandro Colomar
  2021-10-29 20:27   ` Is getpass(3) really obsolete? Jeff King
  3 siblings, 2 replies; 24+ messages in thread
From: rsbecker @ 2021-10-29 12:10 UTC (permalink / raw)
  To: 'Alejandro Colomar (man-pages)', 'Libc-alpha',
	'linux-man'
  Cc: git, tech

On October 29, 2021 7:29 AM, Alejandro Colomar wrote:
> On 10/29/21 13:15, Alejandro Colomar wrote:
> > Hi,
> >
> > As the manual pages says, SUSv2 marked it as LEGACY, and POSIX doesn't
> > have it at all.  The manual page goes further and says "This function
> > is obsolete. Do not use it." in its first lines.
> >
> > But, glibc doesn't seem to have deprecated this function at all.  And
> > it seems to be the most portable way to get a password, even if it's
> > not in POSIX.
> >
> > BSDs have readpassphrase(3), but glibc doesn't, so unless you
> > recommend
> 
> OpenBSD also marks getpass(3) as obsolete and recommends
> readpassphrase(3):
> <https://man.openbsd.org/getpass>
> 
> > using readpassphrase(3) from libbsd, or plan to add it to glibc, I
> > think
> > getpass(3) should be the recommended function in Linux, and therefore
> > we should remove the hard words against it.
> >
> > As a real example, git(1) uses getpass(3).
> > <https://github.com/git/git/blob/master/compat/terminal.c>
> >
> > What are your thoughts?

getpass() is obsolete in POSIX.2. However, some platforms still are on POSIX.1, so replacing it instead of providing a configure detection/switch for it might cause issues.

-Randall


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Is getpass(3) really obsolete?
  2021-10-29 11:40   ` Ævar Arnfjörð Bjarmason
@ 2021-10-29 12:11     ` Alejandro Colomar (man-pages)
  2021-10-29 16:31       ` Joseph Myers
  0 siblings, 1 reply; 24+ messages in thread
From: Alejandro Colomar (man-pages) @ 2021-10-29 12:11 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: Libc-alpha, linux-man, git, tech, Benoit Lecocq, Klemens Nanni

Hi Ævar,

On 10/29/21 13:40, Ævar Arnfjörð Bjarmason wrote:
> 
> On Fri, Oct 29 2021, Alejandro Colomar (man-pages) wrote:
> 
>> [Add a few CCs, since I mentioned them.]
> 
> [I'm not sure what the full context of this thread is, but just replying
> from the POV of git@ being CC'd on this]

The first message on this thread was mine from '10/29/21 13:15', so 
you've read it all.

The broader context is that I was trying to make the deprecation notices 
more consistent in the Linux manpages, by using the [[deprecated]] 
attribute where appropriate.  While doing that, I found a few cases 
where the deprecation/obsoletion is not so clear to me, such as this one 
([as]ctime[_r](3) is another one, since it is deprecated by POSIX, but 
not by the C standard, but I'll start a different thread with that; and 
isascii(3) is another one, since the user of it should know if the 
character set he's using is compatible with ascii, and in that case it's 
perfectly valid, it's only a case of garbage in garbage out, IMO).

> 
>> On 10/29/21 13:15, Alejandro Colomar wrote:
>>> Hi,
>>> As the manual pages says, SUSv2 marked it as LEGACY, and POSIX
>>> doesn't have it at all.  The manual page goes further and says "This
>>> function is obsolete. Do not use it." in its first lines.
>>> But, glibc doesn't seem to have deprecated this function at all.
>>> And it seems to be the most portable way to get a password, even if
>>> it's not in POSIX.
>>> BSDs have readpassphrase(3), but glibc doesn't, so unless you
>>> recommend
[...]

Cheers,

Alex

-- 
Alejandro Colomar
Linux man-pages comaintainer; https://www.kernel.org/doc/man-pages/
http://www.alejandro-colomar.es/

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Is getpass(3) really obsolete?
  2021-10-29 12:10   ` rsbecker
@ 2021-10-29 13:55     ` Eugene Syromyatnikov
  2021-10-29 13:55     ` Theo de Raadt
  1 sibling, 0 replies; 24+ messages in thread
From: Eugene Syromyatnikov @ 2021-10-29 13:55 UTC (permalink / raw)
  To: rsbecker; +Cc: Alejandro Colomar (man-pages), Libc-alpha, linux-man, git, tech

On Fri, Oct 29, 2021 at 2:40 PM <rsbecker@nexbridge.com> wrote:
> getpass() is obsolete in POSIX.2. However, some platforms still are on POSIX.1, so replacing it instead of providing a configure detection/switch for it might cause issues.

POSIX.2 is not a newer POSIX version, but rather a book (“Shell and
utilities”) in pre-2001 standard revisions, and it has nothing to do
with the system interfaces (that is POSIX.1).
And the only mention of getpass() in POSIX (at least, since the 2001's
edition) indeed seems to be [1], in the list of functions that have
not been carried forward from XSH5, the 1997 revision of “System
Interfaces and Headers” (that is, SUSv2)[2], where it is inherited
from SUSv1[4] from XPG[5] and, as Alejandro already mentioned, marked
as obsolete, per XPG3 to XPG4 migration guide[6]; the previous, 1988,
version of POSIX[3] does not mention getpass() at all.

[1] https://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap01.html
[2] https://pubs.opengroup.org/onlinepubs/7908799/xsh/getpass.html
[3] https://mirror.math.princeton.edu/pub/oldlinux/download/c953.pdf
[4] https://pubs.opengroup.org/onlinepubs/9695969499/toc.pdf
[5] https://bitsavers.computerhistory.org/pdf/xOpen/X_Open_Portability_Guide_1985/xpg_2_xopen_system_v_specification_2.pdf
[6] http://archive.opengroup.org/publications/archive/CDROM/g501.pdf

-- 
Eugene Syromyatnikov
mailto:evgsyr@gmail.com
xmpp:esyr@jabber.{ru|org}

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Is getpass(3) really obsolete?
  2021-10-29 12:10   ` rsbecker
  2021-10-29 13:55     ` Eugene Syromyatnikov
@ 2021-10-29 13:55     ` Theo de Raadt
  2021-10-29 14:18       ` rsbecker
  2021-10-29 14:53       ` Zack Weinberg
  1 sibling, 2 replies; 24+ messages in thread
From: Theo de Raadt @ 2021-10-29 13:55 UTC (permalink / raw)
  To: rsbecker
  Cc: 'Alejandro Colomar (man-pages)', 'Libc-alpha',
	'linux-man',
	git, tech

<rsbecker@nexbridge.com> wrote:

> On October 29, 2021 7:29 AM, Alejandro Colomar wrote:
> > On 10/29/21 13:15, Alejandro Colomar wrote:
> > > Hi,
> > >
> > > As the manual pages says, SUSv2 marked it as LEGACY, and POSIX doesn't
> > > have it at all.  The manual page goes further and says "This function
> > > is obsolete. Do not use it." in its first lines.
> > >
> > > But, glibc doesn't seem to have deprecated this function at all.  And
> > > it seems to be the most portable way to get a password, even if it's
> > > not in POSIX.
> > >
> > > BSDs have readpassphrase(3), but glibc doesn't, so unless you
> > > recommend
> > 
> > OpenBSD also marks getpass(3) as obsolete and recommends
> > readpassphrase(3):
> > <https://man.openbsd.org/getpass>
> > 
> > > using readpassphrase(3) from libbsd, or plan to add it to glibc, I
> > > think
> > > getpass(3) should be the recommended function in Linux, and therefore
> > > we should remove the hard words against it.
> > >
> > > As a real example, git(1) uses getpass(3).
> > > <https://github.com/git/git/blob/master/compat/terminal.c>
> > >
> > > What are your thoughts?
> 
> getpass() is obsolete in POSIX.2. However, some platforms still are on POSIX.1, so replacing it instead of providing a configure detection/switch for it might cause issues.


The community finally had the balls to get rid of gets(3).

getpass(3) shares the same flaw, that the buffer size isn't passed.
This has been an issue in the past, and incorrectly led to readpassphrase(3)

readpassphrase(3) has a few too many features/extensions for my taste, but
at least it is harder to abuse.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* RE: Is getpass(3) really obsolete?
  2021-10-29 13:55     ` Theo de Raadt
@ 2021-10-29 14:18       ` rsbecker
  2021-10-29 14:21         ` Theo de Raadt
  2021-10-29 14:53       ` Zack Weinberg
  1 sibling, 1 reply; 24+ messages in thread
From: rsbecker @ 2021-10-29 14:18 UTC (permalink / raw)
  To: 'Theo de Raadt'
  Cc: 'Alejandro Colomar (man-pages)', 'Libc-alpha',
	'linux-man',
	git, tech

On October 29, 2021 9:56 AM, Theo de Raadt wrote:
> Subject: Re: Is getpass(3) really obsolete?
> <rsbecker@nexbridge.com> wrote:
> 
> > On October 29, 2021 7:29 AM, Alejandro Colomar wrote:
> > > On 10/29/21 13:15, Alejandro Colomar wrote:
> > > > Hi,
> > > >
> > > > As the manual pages says, SUSv2 marked it as LEGACY, and POSIX
> > > > doesn't have it at all.  The manual page goes further and says
> > > > "This function is obsolete. Do not use it." in its first lines.
> > > >
> > > > But, glibc doesn't seem to have deprecated this function at all.
> > > > And it seems to be the most portable way to get a password, even
> > > > if it's not in POSIX.
> > > >
> > > > BSDs have readpassphrase(3), but glibc doesn't, so unless you
> > > > recommend
> > >
> > > OpenBSD also marks getpass(3) as obsolete and recommends
> > > readpassphrase(3):
> > > <https://man.openbsd.org/getpass>
> > >
> > > > using readpassphrase(3) from libbsd, or plan to add it to glibc, I
> > > > think
> > > > getpass(3) should be the recommended function in Linux, and
> > > > therefore we should remove the hard words against it.
> > > >
> > > > As a real example, git(1) uses getpass(3).
> > > > <https://github.com/git/git/blob/master/compat/terminal.c>
> > > >
> > > > What are your thoughts?
> >
> > getpass() is obsolete in POSIX.2. However, some platforms still are on
POSIX.1,
> so replacing it instead of providing a configure detection/switch for it
might
> cause issues.
> 
> 
> The community finally had the balls to get rid of gets(3).
> 
> getpass(3) shares the same flaw, that the buffer size isn't passed.
> This has been an issue in the past, and incorrectly led to
readpassphrase(3)
> 
> readpassphrase(3) has a few too many features/extensions for my taste, but
at
> least it is harder to abuse.

readpassphrase is not generally supported. This will break builds on many
platforms.


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Is getpass(3) really obsolete?
  2021-10-29 14:18       ` rsbecker
@ 2021-10-29 14:21         ` Theo de Raadt
  2021-10-29 14:33           ` rsbecker
  0 siblings, 1 reply; 24+ messages in thread
From: Theo de Raadt @ 2021-10-29 14:21 UTC (permalink / raw)
  To: rsbecker
  Cc: 'Alejandro Colomar (man-pages)', 'Libc-alpha',
	'linux-man',
	git, tech

<rsbecker@nexbridge.com> wrote:

> > > getpass() is obsolete in POSIX.2. However, some platforms still are on
> POSIX.1,
> > so replacing it instead of providing a configure detection/switch for it
> might
> > cause issues.
> > 
> > 
> > The community finally had the balls to get rid of gets(3).
> > 
> > getpass(3) shares the same flaw, that the buffer size isn't passed.
> > This has been an issue in the past, and incorrectly led to
> readpassphrase(3)
> > 
> > readpassphrase(3) has a few too many features/extensions for my taste, but
> at
> > least it is harder to abuse.
> 
> readpassphrase is not generally supported. This will break builds on many
> platforms.

Of course moving forward takes a long time.  If a better API is supplied
then there is a choice in 10 years.  If a better API is not supplied,
then 10 years from now this conversation can get a reply.




^ permalink raw reply	[flat|nested] 24+ messages in thread

* RE: Is getpass(3) really obsolete?
  2021-10-29 14:21         ` Theo de Raadt
@ 2021-10-29 14:33           ` rsbecker
  2021-10-29 14:44             ` Alejandro Colomar (man-pages)
  0 siblings, 1 reply; 24+ messages in thread
From: rsbecker @ 2021-10-29 14:33 UTC (permalink / raw)
  To: 'Theo de Raadt'
  Cc: 'Alejandro Colomar (man-pages)', 'Libc-alpha',
	'linux-man',
	git, tech

October 29, 2031 10:21 AM, Theo de Raadt will write:
> <rsbecker@nexbridge.com> wrote:
> 
> > > > getpass() is obsolete in POSIX.2. However, some platforms still
> > > > are on
> > POSIX.1,
> > > so replacing it instead of providing a configure detection/switch
> > > for it
> > might
> > > cause issues.
> > >
> > >
> > > The community finally had the balls to get rid of gets(3).
> > >
> > > getpass(3) shares the same flaw, that the buffer size isn't passed.
> > > This has been an issue in the past, and incorrectly led to
> > readpassphrase(3)
> > >
> > > readpassphrase(3) has a few too many features/extensions for my
> > > taste, but
> > at
> > > least it is harder to abuse.
> >
> > readpassphrase is not generally supported. This will break builds on
> > many platforms.
> 
> Of course moving forward takes a long time.  If a better API is supplied then
> there is a choice in 10 years.  If a better API is not supplied, then 10 years from
> now this conversation can get a reply.

I checked the API 10 years from now (check the above date) at it's still not there 😉 In the meantime, compatibility is important. I checked the latest release (last week's) on my platform and readpassphrase() is not available. Let's please put a compatibility layer in.


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Is getpass(3) really obsolete?
  2021-10-29 14:33           ` rsbecker
@ 2021-10-29 14:44             ` Alejandro Colomar (man-pages)
  2021-10-29 15:00               ` rsbecker
  0 siblings, 1 reply; 24+ messages in thread
From: Alejandro Colomar (man-pages) @ 2021-10-29 14:44 UTC (permalink / raw)
  To: rsbecker, 'Theo de Raadt'
  Cc: 'Libc-alpha', 'linux-man', git, tech

Hi Randall, Theo,

On 10/29/21 16:33, rsbecker@nexbridge.com wrote:
> October 29, 2031 10:21 AM, Theo de Raadt will write:
>> <rsbecker@nexbridge.com> wrote:
>>
>>>>> getpass() is obsolete in POSIX.2. However, some platforms still
>>>>> are on
>>> POSIX.1,
>>>> so replacing it instead of providing a configure detection/switch
>>>> for it
>>> might
>>>> cause issues.
>>>>
>>>>
>>>> The community finally had the balls to get rid of gets(3).
>>>>
>>>> getpass(3) shares the same flaw, that the buffer size isn't passed.
>>>> This has been an issue in the past, and incorrectly led to
>>> readpassphrase(3)

That seems a good reason to keep the "Do not use it." note in the manual 
page.  I think I'll add a recommendation for readpassphrase(3bsd) for 
the moment which is the only alternative available in Linux.

>>>>
>>>> readpassphrase(3) has a few too many features/extensions for my
>>>> taste, but
>>> at
>>>> least it is harder to abuse.
>>>
>>> readpassphrase is not generally supported. This will break builds on
>>> many platforms.
I found readpassphrase(3) in FreeBSD and OpenBSD.
It is also present in libbsd(7), which is available in most Linux 
distributions.
I also found it on a Mac that I have access.

NetBSD has getpass_r(3) instead.  It is not in any other system I have 
access.


>>
>> Of course moving forward takes a long time.  If a better API is supplied then
>> there is a choice in 10 years.  If a better API is not supplied, then 10 years from
>> now this conversation can get a reply.
> 
> I checked the API 10 years from now (check the above date) at it's still not there 😉 In the meantime, compatibility is important. I checked the latest release (last week's) on my platform and readpassphrase() is not available. Let's please put a compatibility layer in.
> 
libbsd(7) is probably the compatibility layer that you're looking for. 
What system are you on?

<https://libbsd.freedesktop.org/wiki/>

Cheers,

Alex


-- 
Alejandro Colomar
Linux man-pages comaintainer; https://www.kernel.org/doc/man-pages/
http://www.alejandro-colomar.es/

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Is getpass(3) really obsolete?
  2021-10-29 13:55     ` Theo de Raadt
  2021-10-29 14:18       ` rsbecker
@ 2021-10-29 14:53       ` Zack Weinberg
  2022-09-27 19:19         ` readpassphrase(3) in glibc, and agetpass() (Was: Is getpass(3) really obsolete?) Alejandro Colomar
  1 sibling, 1 reply; 24+ messages in thread
From: Zack Weinberg @ 2021-10-29 14:53 UTC (permalink / raw)
  To: Theo de Raadt, rsbecker, 'Alejandro Colomar (man-pages)',
	'linux-man',
	tech, Florian Weimer, git

On Fri, Oct 29, 2021, at 9:55 AM, Theo de Raadt wrote:
> <rsbecker@nexbridge.com> wrote:
>> On October 29, 2021 7:29 AM, Alejandro Colomar wrote:
>> > On 10/29/21 13:15, Alejandro Colomar wrote:
>> > > Hi,
>> > >
>> > > As the manual pages says, SUSv2 marked it as LEGACY, and POSIX doesn't
>> > > have it at all.  The manual page goes further and says "This function
>> > > is obsolete. Do not use it." in its first lines.
...
> The community finally had the balls to get rid of gets(3).
>
> getpass(3) shares the same flaw, that the buffer size isn't passed.
> This has been an issue in the past

I was about to post exactly the same thing.  getpass(3) is not deprecated because there's a better replacement, it's deprecated because it's _unsafe_.  The glibc implementation wraps getline(3) and therefore  doesn't truncate the passphrase or overflow a fixed-size buffer, no matter how long the input is, but portable code cannot rely on that.  And come to think of it, using getline(3) means that prefixes of the passphrase may be left lying around in malloc's free lists.

(getpass also cannot be made thread safe, due to recycling of a static buffer, but a program in which multiple threads are racing to prompt the user for passwords would be a UX disaster anyway, so I don't think that's a critical flaw the way it is for e.g. strtok(3).)

The Linux manpage project's documentation is, as I understand it, for Linux with glibc _first_, but not _only_; it should not describe this function as not-deprecated just because glibc has patched its worst problems and doesn't offer any better API.

> readpassphrase(3) has a few too many features/extensions for my taste, but
> at least it is harder to abuse.

I am inclined to agree that readpassphrase has too many knobs, and I can't think of any legitimate present-day use for several of them, which is not a good property for an API handling security-critical data.  Also, it relies on the caller to size the buffer for the passphrase, and therefore risks truncating people's passphrases.

With my libxcrypt hat on I've thought a bit about replacements for getpass.  The conclusion I came to is that the easy changes are all putting lipstick on a pig, and if I was going to work on this at all I was going to design a privilege-separated authentication service that could be asked to take over a tty, read a passphrase, check it, and return just success or failure to the caller.  Neither the passphrase itself, nor any strings derived from it, would ever be in the caller's address space.  But this is obviously well out of scope for the C library.

zw

^ permalink raw reply	[flat|nested] 24+ messages in thread

* RE: Is getpass(3) really obsolete?
  2021-10-29 14:44             ` Alejandro Colomar (man-pages)
@ 2021-10-29 15:00               ` rsbecker
  0 siblings, 0 replies; 24+ messages in thread
From: rsbecker @ 2021-10-29 15:00 UTC (permalink / raw)
  To: 'Alejandro Colomar (man-pages)', 'Theo de Raadt'
  Cc: 'Libc-alpha', 'linux-man', git, tech

On October 29, 2021 10:45 AM, Alejandro Colomar wrote:
> On 10/29/21 16:33, rsbecker@nexbridge.com wrote:
> > October 29, 2031 10:21 AM, Theo de Raadt will write:
> >> <rsbecker@nexbridge.com> wrote:
> >>
> >>>>> getpass() is obsolete in POSIX.2. However, some platforms still
> >>>>> are on
> >>> POSIX.1,
> >>>> so replacing it instead of providing a configure detection/switch
> >>>> for it
> >>> might
> >>>> cause issues.
> >>>>
> >>>>
> >>>> The community finally had the balls to get rid of gets(3).
> >>>>
> >>>> getpass(3) shares the same flaw, that the buffer size isn't passed.
> >>>> This has been an issue in the past, and incorrectly led to
> >>> readpassphrase(3)
> 
> That seems a good reason to keep the "Do not use it." note in the manual page.
> I think I'll add a recommendation for readpassphrase(3bsd) for the moment
> which is the only alternative available in Linux.
> 
> >>>>
> >>>> readpassphrase(3) has a few too many features/extensions for my
> >>>> taste, but
> >>> at
> >>>> least it is harder to abuse.
> >>>
> >>> readpassphrase is not generally supported. This will break builds on
> >>> many platforms.
> I found readpassphrase(3) in FreeBSD and OpenBSD.
> It is also present in libbsd(7), which is available in most Linux distributions.
> I also found it on a Mac that I have access.
> 
> NetBSD has getpass_r(3) instead.  It is not in any other system I have access.
> 
> 
> >>
> >> Of course moving forward takes a long time.  If a better API is supplied then
> >> there is a choice in 10 years.  If a better API is not supplied, then 10 years
> from
> >> now this conversation can get a reply.
> >
> > I checked the API 10 years from now (check the above date) at it's still not
> there 😉 In the meantime, compatibility is important. I checked the latest
> release (last week's) on my platform and readpassphrase() is not available. Let's
> please put a compatibility layer in.
> >
> libbsd(7) is probably the compatibility layer that you're looking for.
> What system are you on?
> 
> <https://libbsd.freedesktop.org/wiki/>

I am on two variants (x86 and ia64) of HPE NonStop with current operating systems - and I do the build/test for git and OpenSSL. getpass() an alias to getpass2() but the other procs are not present. If this is going into git, I would suggest putting something into compat.c to abstract out the call. If it's there, we can handle it on a platform-by-platform basis.

Thanks,
Randall


^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH] getpass.3: SYNOPSIS: Mark getpass() as [[deprecated]]
  2021-10-29 11:28 ` Alejandro Colomar (man-pages)
  2021-10-29 11:40   ` Ævar Arnfjörð Bjarmason
  2021-10-29 12:10   ` rsbecker
@ 2021-10-29 15:27   ` Alejandro Colomar
  2021-10-29 20:27   ` Is getpass(3) really obsolete? Jeff King
  3 siblings, 0 replies; 24+ messages in thread
From: Alejandro Colomar @ 2021-10-29 15:27 UTC (permalink / raw)
  To: mtk.manpages, linux-man
  Cc: Alejandro Colomar, Git, Glibc, OpenBSD,
	Ævar Arnfjörð Bjarmason, Benoit Lecocq,
	Klemens Nanni, Randall, Eugene Syromyatnikov, Theo de Raadt,
	Zack Weinberg

Suggest readpassphrase(3bsd) as an alternative.

See the long discussion in the mailing list for more details (link
at the bottom of this commit message).  I'll quote some relevant
parts here:

Eugene Syromyatnikov <evgsyr@gmail.com>:
{
	And the only mention of getpass() in POSIX (at least,
	since the 2001's edition) indeed seems to be [1], in the
	list of functions that have not been carried forward from
	XSH5, the 1997 revision of “System Interfaces and Headers”
	(that is, SUSv2)[2], where it is inherited from SUSv1[4]
	from XPG[5] and, as Alejandro already mentioned, marked as
	obsolete, per XPG3 to XPG4 migration guide[6]; the
	previous, 1988, version of POSIX[3] does not mention
	getpass() at all.

	[1] https://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap01.html
	[2] https://pubs.opengroup.org/onlinepubs/7908799/xsh/getpass.html
	[3] https://mirror.math.princeton.edu/pub/oldlinux/download/c953.pdf
	[4] https://pubs.opengroup.org/onlinepubs/9695969499/toc.pdf
	[5] https://bitsavers.computerhistory.org/pdf/xOpen/X_Open_Portability_Guide_1985/xpg_2_xopen_system_v_specification_2.pdf
	[6] http://archive.opengroup.org/publications/archive/CDROM/g501.pdf
}

Theo de Raadt <deraadt@openbsd.org>:
{
	The community finally had the balls to get rid of gets(3).

	getpass(3) shares the same flaw, that the buffer size
	isn't passed.  This has been an issue in the past, and
	incorrectly led to readpassphrase(3).

	readpassphrase(3) has a few too many features/extensions
	for my taste, but at least it is harder to abuse.
}

Alejandro Colomar <alx.manpages@gmail.com>:
{
	I found readpassphrase(3) in FreeBSD and OpenBSD.  It is
	also present in libbsd(7), which is available in most
	Linux distributions.  I also found it on a Mac that I have
	access.

	NetBSD has getpass_r(3) instead.  It is not in any other
	system I have access.
}

Zack Weinberg <zack@owlfolio.org>:
{
	I was about to post exactly the same thing.  getpass(3)
	is not deprecated because there's a better replacement,
	it's deprecated because it's _unsafe_.  The glibc
	implementation wraps getline(3) and therefore  doesn't
	truncate the passphrase or overflow a fixed-size buffer,
	no matter how long the input is, but portable code cannot
	rely on that.  And come to think of it, using getline(3)
	means that prefixes of the passphrase may be left lying
	around in malloc's free lists.

	(getpass also cannot be made thread safe, due to recycling
	of a static buffer, but a program in which multiple
	threads are racing to prompt the user for passwords would
	be a UX disaster anyway, so I don't think that's a
	critical flaw the way it is for e.g. strtok(3).)

	The Linux manpage project's documentation is, as I
	understand it, for Linux with glibc _first_, but not
	_only_; it should not describe this function as
	not-deprecated just because glibc has patched its worst
	problems and doesn't offer any better API.
}

List: linux-man <https://lore.kernel.org/linux-man/6d8642e9-71f7-4a83-9791-880d04f67d17@www.fastmail.com/T/#t>
Signed-off-by: Alejandro Colomar <alx.manpages@gmail.com>
Cc: Git <git@vger.kernel.org>
Cc: Glibc <libc-alpha@sourceware.org>
Cc: OpenBSD <tech@openbsd.org>
Cc: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Cc: Benoit Lecocq <benoit@openbsd.org>
Cc: Klemens Nanni <kn@openbsd.org>
Cc: Randall <rsbecker@nexbridge.com>
Cc: Eugene Syromyatnikov <evgsyr@gmail.com>
Cc: Theo de Raadt <deraadt@openbsd.org>
Cc: Zack Weinberg <zack@owlfolio.org>
Cc: Florian Weimer <libc-alpha@sourceware.org>
---
 man3/getpass.3 | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/man3/getpass.3 b/man3/getpass.3
index fa2031544..7d6da07fa 100644
--- a/man3/getpass.3
+++ b/man3/getpass.3
@@ -28,7 +28,7 @@ getpass \- get a password
 .nf
 .B #include <unistd.h>
 .PP
-.BI "char *getpass(const char *" prompt );
+.BI "[[deprecated]] char *getpass(const char *" prompt );
 .fi
 .PP
 .RS -4
@@ -48,6 +48,7 @@ Feature Test Macro Requirements for glibc (see
 .SH DESCRIPTION
 This function is obsolete.
 Do not use it.
+See NOTES.
 If you want to read input without terminal echoing enabled,
 see the description of the
 .I ECHO
@@ -126,7 +127,11 @@ Removed in POSIX.1-2001.
 .\" are transmitted as part of the password.
 .\" Since libc 5.4.19 also line editing is disabled, so that also
 .\" backspace and the like will be seen as part of the password.
-.
+You should use instead
+.BR readpassphrase (3bsd),
+provided by
+.IR libbsd .
+.PP
 In the GNU C library implementation, if
 .I /dev/tty
 cannot be opened, the prompt is written to
-- 
2.33.1


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Is getpass(3) really obsolete?
  2021-10-29 12:11     ` Alejandro Colomar (man-pages)
@ 2021-10-29 16:31       ` Joseph Myers
  2021-10-30 12:24         ` Alejandro Colomar (man-pages)
  0 siblings, 1 reply; 24+ messages in thread
From: Joseph Myers @ 2021-10-29 16:31 UTC (permalink / raw)
  To: Alejandro Colomar (man-pages)
  Cc: Ævar Arnfjörð Bjarmason, linux-man, Libc-alpha,
	tech, Klemens Nanni, Benoit Lecocq, git

On Fri, 29 Oct 2021, Alejandro Colomar (man-pages) via Libc-alpha wrote:

> The broader context is that I was trying to make the deprecation notices more
> consistent in the Linux manpages, by using the [[deprecated]] attribute where
> appropriate.  While doing that, I found a few cases where the
> deprecation/obsoletion is not so clear to me, such as this one
> ([as]ctime[_r](3) is another one, since it is deprecated by POSIX, but not by
> the C standard, but I'll start a different thread with that; and isascii(3) is

See the discussion of deprecation starting with 
<https://sourceware.org/pipermail/libc-alpha/2021-May/126356.html> (C2X 
has also deprecated those functions).  The comments in that thread 
supported marking the functions deprecated, but it needs someone to send a 
patch and I don't know what breakage might result in applications using 
those functions.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Is getpass(3) really obsolete?
  2021-10-29 11:28 ` Alejandro Colomar (man-pages)
                     ` (2 preceding siblings ...)
  2021-10-29 15:27   ` [PATCH] getpass.3: SYNOPSIS: Mark getpass() as [[deprecated]] Alejandro Colomar
@ 2021-10-29 20:27   ` Jeff King
  3 siblings, 0 replies; 24+ messages in thread
From: Jeff King @ 2021-10-29 20:27 UTC (permalink / raw)
  To: Alejandro Colomar (man-pages); +Cc: Libc-alpha, linux-man, git, tech

On Fri, Oct 29, 2021 at 01:28:56PM +0200, Alejandro Colomar (man-pages) wrote:

> > As a real example, git(1) uses getpass(3).
> > <https://github.com/git/git/blob/master/compat/terminal.c>

Sort of. It is the compile-time fallback of last resort. Most builds
would use either termios with /dev/tty or a Windows-native equivalent.

You can see all the reasons we stopped using getpass() in the commit
below.

-- >8 --
commit 21aeafceda2382d26bfa73a98ba45a937d65d77a
Author: Jeff King <peff@peff.net>
Date:   Sat Dec 10 05:41:01 2011 -0500

    add generic terminal prompt function
    
    When we need to prompt the user for input interactively, we
    want to access their terminal directly. We can't rely on
    stdio because it may be connected to pipes or files, rather
    than the terminal. Instead, we use "getpass()", because it
    abstracts the idea of prompting and reading from the
    terminal.  However, it has some problems:
    
      1. It never echoes the typed characters, which makes it OK
         for passwords but annoying for other input (like usernames).
    
      2. Some implementations of getpass() have an extremely
         small input buffer (e.g., Solaris 8 is reported to
         support only 8 characters).
    
      3. Some implementations of getpass() will fall back to
         reading from stdin (e.g., glibc). We explicitly don't
         want this, because our stdin may be connected to a pipe
         speaking a particular protocol, and reading will
         disrupt the protocol flow (e.g., the remote-curl
         helper).
    
      4. Some implementations of getpass() turn off signals, so
         that hitting "^C" on the terminal does not break out of
         the password prompt. This can be a mild annoyance.
    
    Instead, let's provide an abstract "git_terminal_prompt"
    function that addresses these concerns. This patch includes
    an implementation based on /dev/tty, enabled by setting
    HAVE_DEV_TTY. The fallback is to use getpass() as before.
    
    Signed-off-by: Jeff King <peff@peff.net>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Is getpass(3) really obsolete?
  2021-10-29 16:31       ` Joseph Myers
@ 2021-10-30 12:24         ` Alejandro Colomar (man-pages)
  2021-11-01 21:31           ` Joseph Myers
  0 siblings, 1 reply; 24+ messages in thread
From: Alejandro Colomar (man-pages) @ 2021-10-30 12:24 UTC (permalink / raw)
  To: Joseph Myers
  Cc: Ævar Arnfjörð Bjarmason, linux-man, Libc-alpha,
	tech, Klemens Nanni, Benoit Lecocq, git

Hi Joseph,

On 10/29/21 18:31, Joseph Myers wrote:
> On Fri, 29 Oct 2021, Alejandro Colomar (man-pages) via Libc-alpha wrote:
> 
>> The broader context is that I was trying to make the deprecation notices more
>> consistent in the Linux manpages, by using the [[deprecated]] attribute where
>> appropriate.  While doing that, I found a few cases where the
>> deprecation/obsoletion is not so clear to me, such as this one
>> ([as]ctime[_r](3) is another one, since it is deprecated by POSIX, but not by
>> the C standard, but I'll start a different thread with that; and isascii(3) is
> 
> See the discussion of deprecation starting with
> <https://sourceware.org/pipermail/libc-alpha/2021-May/126356.html> (C2X
> has also deprecated those functions).  The comments in that thread
> supported marking the functions deprecated, but it needs someone to send a
> patch and I don't know what breakage might result in applications using
> those functions.
> 

Thanks.  The latest draft for C2x that I know of is N2596.  Is there any 
newer draft that I can consult for these things?  I see many proposals, 
but it's difficult to know which have been accepted and which not 
without an actual recent draft of the standard.

Cheers,

Alex


-- 
Alejandro Colomar
Linux man-pages comaintainer; https://www.kernel.org/doc/man-pages/
http://www.alejandro-colomar.es/

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Is getpass(3) really obsolete?
  2021-10-30 12:24         ` Alejandro Colomar (man-pages)
@ 2021-11-01 21:31           ` Joseph Myers
  0 siblings, 0 replies; 24+ messages in thread
From: Joseph Myers @ 2021-11-01 21:31 UTC (permalink / raw)
  To: Alejandro Colomar (man-pages)
  Cc: linux-man, Libc-alpha, Ævar Arnfjörð Bjarmason,
	tech, Klemens Nanni, Benoit Lecocq, git

On Sat, 30 Oct 2021, Alejandro Colomar (man-pages) via Libc-alpha wrote:

> > See the discussion of deprecation starting with
> > <https://sourceware.org/pipermail/libc-alpha/2021-May/126356.html> (C2X
> > has also deprecated those functions).  The comments in that thread
> > supported marking the functions deprecated, but it needs someone to send a
> > patch and I don't know what breakage might result in applications using
> > those functions.
> 
> Thanks.  The latest draft for C2x that I know of is N2596.  Is there any newer
> draft that I can consult for these things?  I see many proposals, but it's

The latest public draft is N2731, but there are still various accepted 
proposals not included in there, including N2566 (wording version 2) which 
I believe was accepted in October 2020 (I think issue 68 in the (private) 
C standard GitLab, for integrating that paper, has been incorrectly closed 
without integrating it).

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 24+ messages in thread

* readpassphrase(3) in glibc, and agetpass() (Was: Is getpass(3) really obsolete?)
  2021-10-29 14:53       ` Zack Weinberg
@ 2022-09-27 19:19         ` Alejandro Colomar
  2022-09-27 19:33           ` Alex Colomar
                             ` (2 more replies)
  0 siblings, 3 replies; 24+ messages in thread
From: Alejandro Colomar @ 2022-09-27 19:19 UTC (permalink / raw)
  To: Zack Weinberg, Theo de Raadt, rsbecker, 'linux-man',
	tech, Florian Weimer, git

Hi Zack,

On 10/29/21 16:53, Zack Weinberg via Libc-alpha wrote:
> On Fri, Oct 29, 2021, at 9:55 AM, Theo de Raadt wrote:
>> <rsbecker@nexbridge.com> wrote:
>>> On October 29, 2021 7:29 AM, Alejandro Colomar wrote:
>>>> On 10/29/21 13:15, Alejandro Colomar wrote:
>>>>> Hi,
>>>>>
>>>>> As the manual pages says, SUSv2 marked it as LEGACY, and POSIX doesn't
>>>>> have it at all.  The manual page goes further and says "This function
>>>>> is obsolete. Do not use it." in its first lines.
> ...
>> The community finally had the balls to get rid of gets(3).
>>
>> getpass(3) shares the same flaw, that the buffer size isn't passed.
>> This has been an issue in the past
> 
> I was about to post exactly the same thing.  getpass(3) is not deprecated because there's a better replacement, it's deprecated because it's _unsafe_.  The glibc implementation wraps getline(3) and therefore  doesn't truncate the passphrase or overflow a fixed-size buffer, no matter how long the input is, but portable code cannot rely on that.  And come to think of it, using getline(3) means that prefixes of the passphrase may be left lying around in malloc's free lists.
> 
> (getpass also cannot be made thread safe, due to recycling of a static buffer, but a program in which multiple threads are racing to prompt the user for passwords would be a UX disaster anyway, so I don't think that's a critical flaw the way it is for e.g. strtok(3).)
> 
> The Linux manpage project's documentation is, as I understand it, for Linux with glibc _first_, but not _only_; it should not describe this function as not-deprecated just because glibc has patched its worst problems and doesn't offer any better API.
> 
>> readpassphrase(3) has a few too many features/extensions for my taste, but
>> at least it is harder to abuse.
> 
> I am inclined to agree that readpassphrase has too many knobs, and I can't think of any legitimate present-day use for several of them, which is not a good property for an API handling security-critical data.  Also, it relies on the caller to size the buffer for the passphrase, and therefore risks truncating people's passphrases.
> 
> With my libxcrypt hat on I've thought a bit about replacements for getpass.  The conclusion I came to is that the easy changes are all putting lipstick on a pig, and if I was going to work on this at all I was going to design a privilege-separated authentication service that could be asked to take over a tty, read a passphrase, check it, and return just success or failure to the caller.  Neither the passphrase itself, nor any strings derived from it, would ever be in the caller's address space.  But this is obviously well out of scope for the C library.
> 
> zw

I happen to be working on replacing getpass(3) in shadow-utils.  As 
there is no replacement in glibc, I'm making the code depend on libbsd 
on GNU systems.

I developed a function similar to getpass(3), but which allocates a 
buffer (similar to asprintf(3)).  I only allocate once, and bail out if 
the password exceeds PASS_MAX, so no leaks in allocated memory (modulo 
bugs that I may have not noticed).

I also enforce both clearing and freeing the memory, by requiring a 
specific clean-up function.

The prototypes for the function and the clean-up are:

```
void erase_pass(char *p);
[[gnu::malloc(erase_pass)]] char *shdw_getpass(const char *prompt);

```

And the implementation is:

```
#include "prototypes.h"

#include <limits.h>
#include <readpassphrase.h>
#include <stdio.h>
#include <stdlib.h>


#if !defined(PASS_MAX)
#define PASS_MAX  BUFSIZ
#endif


char *
agetpass(const char *prompt)
{
	char    *p;
	size_t  len;

	p = malloc(PASS_MAX);
	if (p == NULL)
		return NULL;

	if (readpassphrase(prompt, p, PASS_MAX, 0) == NULL)
		goto fail;

	len = strlen(p);

	if (len == 0)
		return p;

	if (p[len - 1] != '\n')
		goto truncated;

	p[len - 1] = '\0';

	return p;

truncated:
	memzero(p, PASS_MAX);
fail:
	free(p);
	return NULL;
}


void
erase_pass(char *p)
{
	if (p != NULL)
		memzero(p, PASS_MAX);
	free(p);
}
```


Would you mind implementing readpassphrase(3) in glibc so that it's 
easier to use something safe and portable without resorting to 
compatibility libraries?  Also, I'd like some review of this function, 
if you think the API could be improved.  Maybe agetpass() would be a 
simple almost-drop-in replacement for getpass(3), so if you like it for 
glibc, let's discuss it.

I chose a predefined buffer size to not have to pass a buffer size all 
the time, which could be error-prone.  I also allocated the buffer 
internally, to make it easier to replace getpass(3).  It may be 
desirable to use existing buffers, and pass them through a pointer, but 
for shadow-utils, it was simpler to keep the getpass(3) API.

I don't know what was the practice with PASS_MAX regarding the NUL byte, 
but to avoid creating a buffer of a power of two plus one, I decided 
that the NUL byte would be within PASS_MAX.  Another solution would be 
to declare PASS_MAX to be something like BUFSIZ-1, and then use 
PASS_MAX+1, but I opted for simplicity.

What are your thoughts?

Cheers,

Alex

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: readpassphrase(3) in glibc, and agetpass() (Was: Is getpass(3) really obsolete?)
  2022-09-27 19:19         ` readpassphrase(3) in glibc, and agetpass() (Was: Is getpass(3) really obsolete?) Alejandro Colomar
@ 2022-09-27 19:33           ` Alex Colomar
  2022-09-27 20:30           ` Sam James
  2022-09-27 20:52           ` readpassphrase(3) in glibc, and agetpass() Junio C Hamano
  2 siblings, 0 replies; 24+ messages in thread
From: Alex Colomar @ 2022-09-27 19:33 UTC (permalink / raw)
  To: Zack Weinberg, Theo de Raadt, rsbecker, 'linux-man',
	tech, Florian Weimer, git


[-- Attachment #1.1: Type: text/plain, Size: 375 bytes --]

On 9/27/22 21:19, Alejandro Colomar wrote:
...
> 
> The prototypes for the function and the clean-up are:
> 
> ```
> void erase_pass(char *p);
> [[gnu::malloc(erase_pass)]] char *shdw_getpass(const char *prompt);

I edited the function name for the email, and forgot to fix it here :)

s/shdw_/a/

Cheers,

Alex


-- 
<http://www.alejandro-colomar.es/>


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: readpassphrase(3) in glibc, and agetpass() (Was: Is getpass(3) really obsolete?)
  2022-09-27 19:19         ` readpassphrase(3) in glibc, and agetpass() (Was: Is getpass(3) really obsolete?) Alejandro Colomar
  2022-09-27 19:33           ` Alex Colomar
@ 2022-09-27 20:30           ` Sam James
  2022-09-27 21:00             ` Zack Weinberg
  2022-09-27 20:52           ` readpassphrase(3) in glibc, and agetpass() Junio C Hamano
  2 siblings, 1 reply; 24+ messages in thread
From: Sam James @ 2022-09-27 20:30 UTC (permalink / raw)
  To: Alejandro Colomar
  Cc: Zack Weinberg, Theo de Raadt, rsbecker, linux-man, tech,
	Florian Weimer, git

[-- Attachment #1: Type: text/plain, Size: 3863 bytes --]



> On 27 Sep 2022, at 20:19, Alejandro Colomar via Libc-alpha <libc-alpha@sourceware.org> wrote:
> 
> Hi Zack,
> 
> On 10/29/21 16:53, Zack Weinberg via Libc-alpha wrote:
>> On Fri, Oct 29, 2021, at 9:55 AM, Theo de Raadt wrote:
>>> <rsbecker@nexbridge.com> wrote:
>>>> On October 29, 2021 7:29 AM, Alejandro Colomar wrote:
>>>>> On 10/29/21 13:15, Alejandro Colomar wrote:
>>>>>> Hi,
>>>>>> 
>>>>>> As the manual pages says, SUSv2 marked it as LEGACY, and POSIX doesn't
>>>>>> have it at all.  The manual page goes further and says "This function
>>>>>> is obsolete. Do not use it." in its first lines.
>> ...
>>> The community finally had the balls to get rid of gets(3).
>>> 
>>> getpass(3) shares the same flaw, that the buffer size isn't passed.
>>> This has been an issue in the past
>> I was about to post exactly the same thing.  getpass(3) is not deprecated because there's a better replacement, it's deprecated because it's _unsafe_.  The glibc implementation wraps getline(3) and therefore  doesn't truncate the passphrase or overflow a fixed-size buffer, no matter how long the input is, but portable code cannot rely on that.  And come to think of it, using getline(3) means that prefixes of the passphrase may be left lying around in malloc's free lists.
>> (getpass also cannot be made thread safe, due to recycling of a static buffer, but a program in which multiple threads are racing to prompt the user for passwords would be a UX disaster anyway, so I don't think that's a critical flaw the way it is for e.g. strtok(3).)
>> The Linux manpage project's documentation is, as I understand it, for Linux with glibc _first_, but not _only_; it should not describe this function as not-deprecated just because glibc has patched its worst problems and doesn't offer any better API.
>>> readpassphrase(3) has a few too many features/extensions for my taste, but
>>> at least it is harder to abuse.
>> I am inclined to agree that readpassphrase has too many knobs, and I can't think of any legitimate present-day use for several of them, which is not a good property for an API handling security-critical data.  Also, it relies on the caller to size the buffer for the passphrase, and therefore risks truncating people's passphrases.
>> With my libxcrypt hat on I've thought a bit about replacements for getpass.  The conclusion I came to is that the easy changes are all putting lipstick on a pig, and if I was going to work on this at all I was going to design a privilege-separated authentication service that could be asked to take over a tty, read a passphrase, check it, and return just success or failure to the caller.  Neither the passphrase itself, nor any strings derived from it, would ever be in the caller's address space.  But this is obviously well out of scope for the C library.
>> zw
> 
> I happen to be working on replacing getpass(3) in shadow-utils.  As there is no replacement in glibc, I'm making the code depend on libbsd on GNU systems.
> 
> I developed a function similar to getpass(3), but which allocates a buffer (similar to asprintf(3)).  I only allocate once, and bail out if the password exceeds PASS_MAX, so no leaks in allocated memory (modulo bugs that I may have not noticed).
> 
> I also enforce both clearing and freeing the memory, by requiring a specific clean-up function.
> 
> The prototypes for the function and the clean-up are:
> 
> [snip]
> Would you mind implementing readpassphrase(3) in glibc so that it's easier to use something safe and portable without resorting to compatibility libraries?  Also, I'd like some review of this function, if you think the API could be improved.  Maybe agetpass() would be a simple almost-drop-in replacement for getpass(3), so if you like it for glibc, let's discuss it.
> 
I assume it'd be libxcrypt instead?

Best,
sam

[-- Attachment #2: Message signed with OpenPGP --]
[-- Type: application/pgp-signature, Size: 358 bytes --]

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: readpassphrase(3) in glibc, and agetpass()
  2022-09-27 19:19         ` readpassphrase(3) in glibc, and agetpass() (Was: Is getpass(3) really obsolete?) Alejandro Colomar
  2022-09-27 19:33           ` Alex Colomar
  2022-09-27 20:30           ` Sam James
@ 2022-09-27 20:52           ` Junio C Hamano
  2 siblings, 0 replies; 24+ messages in thread
From: Junio C Hamano @ 2022-09-27 20:52 UTC (permalink / raw)
  To: Alejandro Colomar
  Cc: Zack Weinberg, Theo de Raadt, rsbecker, 'linux-man',
	tech, Florian Weimer

Alejandro Colomar <alx.manpages@gmail.com> writes:

> I happen to be working on replacing getpass(3) in shadow-utils.  As
> there is no replacement in glibc, I'm making the code depend on libbsd
> on GNU systems.
> ...
> Would you mind implementing readpassphrase(3) in glibc so that it's
> easier to use something safe and portable without resorting to
> compatibility libraries?  Also, I'd like some review of this function,
> if you think the API could be improved.  Maybe agetpass() would be a
> simple almost-drop-in replacement for getpass(3), so if you like it
> for glibc, let's discuss it.
>
> I chose a predefined buffer size to not have to pass a buffer size all
> the time, which could be error-prone.  I also allocated the buffer
> internally, to make it easier to replace getpass(3).  It may be
> desirable to use existing buffers, and pass them through a pointer,
> but for shadow-utils, it was simpler to keep the getpass(3) API.
>
> I don't know what was the practice with PASS_MAX regarding the NUL
> byte, but to avoid creating a buffer of a power of two plus one, I
> decided that the NUL byte would be within PASS_MAX.  Another solution
> would be to declare PASS_MAX to be something like BUFSIZ-1, and then
> use PASS_MAX+1, but I opted for simplicity.

I understand that in an old thread last fall we were CC'ed only
because we are one of the users of getpass(3), but could you take us
out of the CC list, please?  We'd migrate, if getpass() starts being
unusable for us, away from it and choose an alternative, but until
then git@vger.kernel.org is a good place to discuss this.

Thanks.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: readpassphrase(3) in glibc, and agetpass() (Was: Is getpass(3) really obsolete?)
  2022-09-27 20:30           ` Sam James
@ 2022-09-27 21:00             ` Zack Weinberg
  2022-09-27 22:41               ` Alejandro Colomar
  0 siblings, 1 reply; 24+ messages in thread
From: Zack Weinberg @ 2022-09-27 21:00 UTC (permalink / raw)
  To: GNU libc development; +Cc: bjoern.esser, alx.manpages

On Tue, Sep 27, 2022, at 4:30 PM, Sam James via Libc-alpha wrote:
>On 27 Sep 2022, at 20:19, Alejandro Colomar via Libc-alpha <libc-alpha@sourceware.org> wrote:
>> I developed a function similar to getpass(3), but which allocates a buffer (similar to asprintf(3)).  I only allocate once, and bail out if the password exceeds PASS_MAX, so no leaks in allocated memory (modulo bugs that I may have not noticed).
...
>> Would you mind implementing readpassphrase(3) in glibc
> I assume it'd be libxcrypt instead?

My immediate reaction is that this is out of scope for libxcrypt.  I could be persuaded otherwise but I don't have much time to work on *either* libxcrypt or libc right now so I won't be able to be very helpful in any event.

I'm cc:ing Bjoern Esser in case he has an opinion.

zw

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: readpassphrase(3) in glibc, and agetpass() (Was: Is getpass(3) really obsolete?)
  2022-09-27 21:00             ` Zack Weinberg
@ 2022-09-27 22:41               ` Alejandro Colomar
  0 siblings, 0 replies; 24+ messages in thread
From: Alejandro Colomar @ 2022-09-27 22:41 UTC (permalink / raw)
  To: Zack Weinberg, GNU libc development; +Cc: bjoern.esser


[-- Attachment #1.1: Type: text/plain, Size: 1139 bytes --]

Hi Zack,

On 9/27/22 23:00, Zack Weinberg wrote:
> On Tue, Sep 27, 2022, at 4:30 PM, Sam James via Libc-alpha wrote:
>> On 27 Sep 2022, at 20:19, Alejandro Colomar via Libc-alpha <libc-alpha@sourceware.org> wrote:
>>> I developed a function similar to getpass(3), but which allocates a buffer (similar to asprintf(3)).  I only allocate once, and bail out if the password exceeds PASS_MAX, so no leaks in allocated memory (modulo bugs that I may have not noticed).
> ...
>>> Would you mind implementing readpassphrase(3) in glibc
>> I assume it'd be libxcrypt instead?
> 
> My immediate reaction is that this is out of scope for libxcrypt.  I could be persuaded otherwise but I don't have much time to work on *either* libxcrypt or libc right now so I won't be able to be very helpful in any event.
> 
> I'm cc:ing Bjoern Esser in case he has an opinion.

Thanks!

BTW, maybe glibc should consider changing the implementation of 
getpass(3) to be in terms of fgets(3) and simply fail for very long 
passwords (PASS_MAX).  That would fix the realloc(3) bug.

Cheers,

Alex


-- 
<http://www.alejandro-colomar.es/>

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2022-09-27 22:41 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-29 11:15 Is getpass(3) really obsolete? Alejandro Colomar
2021-10-29 11:28 ` Alejandro Colomar (man-pages)
2021-10-29 11:40   ` Ævar Arnfjörð Bjarmason
2021-10-29 12:11     ` Alejandro Colomar (man-pages)
2021-10-29 16:31       ` Joseph Myers
2021-10-30 12:24         ` Alejandro Colomar (man-pages)
2021-11-01 21:31           ` Joseph Myers
2021-10-29 12:10   ` rsbecker
2021-10-29 13:55     ` Eugene Syromyatnikov
2021-10-29 13:55     ` Theo de Raadt
2021-10-29 14:18       ` rsbecker
2021-10-29 14:21         ` Theo de Raadt
2021-10-29 14:33           ` rsbecker
2021-10-29 14:44             ` Alejandro Colomar (man-pages)
2021-10-29 15:00               ` rsbecker
2021-10-29 14:53       ` Zack Weinberg
2022-09-27 19:19         ` readpassphrase(3) in glibc, and agetpass() (Was: Is getpass(3) really obsolete?) Alejandro Colomar
2022-09-27 19:33           ` Alex Colomar
2022-09-27 20:30           ` Sam James
2022-09-27 21:00             ` Zack Weinberg
2022-09-27 22:41               ` Alejandro Colomar
2022-09-27 20:52           ` readpassphrase(3) in glibc, and agetpass() Junio C Hamano
2021-10-29 15:27   ` [PATCH] getpass.3: SYNOPSIS: Mark getpass() as [[deprecated]] Alejandro Colomar
2021-10-29 20:27   ` Is getpass(3) really obsolete? Jeff King

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).