New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
agetpass() to replace getpass(3) #573
Conversation
You'll need to add libbsd-dev to build deps right? |
Yep. And in RPM-based distros I guess they call it libbsd-devel. |
b0e0ca4
to
cc08c6e
Compare
Changes: readpassphrase(3): Add RPP_REQUIRE_TTY to flags field. |
cc08c6e
to
831bbeb
Compare
Rebased to master. |
831bbeb
to
2e5adec
Compare
Changes:
|
In which file(s) do you define the build deps? And also the runtime deps, if at all? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added some comments.
Yep. And in RPM-based distros I guess they call it libbsd-devel.
You are right.
@hallyn do we have any policy regarding indentation (tabs vs spaces)? And regarding if
and mandatory block sequences?
2e5adec
to
8186c67
Compare
Changes: Rework indentation in |
8186c67
to
a720f16
Compare
Changes:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The build system needs to be updated.
Draft:
diff --git a/configure.ac b/configure.ac
index 61f2e588..399bb0cb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -393,6 +393,11 @@ if test "$enable_subids" != "no"; then
fi
AM_CONDITIONAL(ENABLE_SUBIDS, test "x$enable_subids" != "xno")
+AC_SEARCH_LIBS([readpassphrase], [bsd],,[AC_MSG_ERROR([readpassphrase() function not found])])
+AC_CHECK_HEADERS([readpassphrase.h], [], [
+ AC_CHECK_HEADERS([bsd/readpassphrase.h], [], [AC_MSG_ERROR([readpassphrase.h header file not found])])
+])
+
AC_SUBST(LIBCRYPT)
AC_CHECK_LIB(crypt, crypt, [LIBCRYPT=-lcrypt],
[AC_MSG_ERROR([crypt() not found])])
diff --git a/libmisc/Makefile.am b/libmisc/Makefile.am
index 3d319cd8..636cc439 100644
--- a/libmisc/Makefile.am
+++ b/libmisc/Makefile.am
@@ -8,6 +8,7 @@ noinst_LTLIBRARIES = libmisc.la
libmisc_la_SOURCES = \
addgrps.c \
age.c \
+ agetpass.c \
audit_help.c \
basename.c \
chkname.c \
diff --git a/libmisc/agetpass.c b/libmisc/agetpass.c
index f6eca4be..edee4e19 100644
--- a/libmisc/agetpass.c
+++ b/libmisc/agetpass.c
@@ -26,8 +26,14 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <config.h>
+
#include <limits.h>
+#ifdef HAVE_READPASSPHRASE_H
#include <readpassphrase.h>
+#elif defined HAVE_BSD_READPASSPHRASE_H
+#include <bsd/readpassphrase.h>
+#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
ca1efa1
to
316a15f
Compare
Changes:
|
[...]
You should always use the
See for example what we do in the Linux man-pages project: |
316a15f
to
b7c02bd
Compare
Changes: Add |
Changes: Hide |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One minor comment left.
Apart from that you should add libbsd-dev
or libbsd-devel
to the package dependencies in the .build
folder. An example of such a file is .builds/ubuntu-focal.yml.
82c6cc5
to
56b629b
Compare
Changes: Add |
4c1da4e
to
97ad87f
Compare
Changes: Added SYNOPSIS to the documentation. |
97ad87f
to
a298bf0
Compare
Changes: cosmetic fix in function documentation |
1435d79
to
f32ab22
Compare
Changes:
|
f32ab22
to
1b3be1b
Compare
Changes: Remove CI bits (already handled in #596 ) |
Changes: Add @ikerexxe changes to CI to test them. |
@@ -887,24 +887,24 @@ | |||
printf (_("Changing the password for group %s\n"), group); | |||
|
|||
for (retries = 0; retries < RETRIES; retries++) { | |||
cp = getpass (_("New Password: ")); | |||
cp = agetpass (_("New Password: ")); |
Check warning
Code scanning / CodeQL
Implicit function declaration
@@ -158,7 +158,7 @@ | |||
* get the password from her, and set the salt for | |||
* the decryption from the group file. | |||
*/ | |||
cp = getpass (_("Password: ")); | |||
cp = agetpass (_("Password: ")); |
Check warning
Code scanning / CodeQL
Implicit function declaration
@@ -204,15 +204,15 @@ | |||
*/ | |||
|
|||
if (!amroot && ('\0' != crypt_passwd[0])) { | |||
clear = getpass (_("Old password: ")); | |||
clear = agetpass (_("Old password: ")); |
Check warning
Code scanning / CodeQL
Implicit function declaration
@@ -286,7 +286,7 @@ | |||
|
|||
warned = false; | |||
for (i = getdef_num ("PASS_CHANGE_TRIES", 5); i > 0; i--) { | |||
cp = getpass (_("New password: ")); | |||
cp = agetpass (_("New password: ")); |
Check warning
Code scanning / CodeQL
Implicit function declaration
@@ -182,7 +182,7 @@ | |||
*/ | |||
|
|||
/* get a password for root */ | |||
cp = getpass (_( | |||
cp = agetpass (_( |
Check warning
Code scanning / CodeQL
Implicit function declaration
4dd00fd
to
85aa820
Compare
Signed-off-by: Alejandro Colomar <alx@kernel.org>
85aa820
to
1abcebf
Compare
…s safely There are several issues with getpass(3). Many implementations of it share the same issues that the infamous gets(3). In glibc it's not so terrible, since it's a wrapper around getline(3). But it still has an important bug: If the password is long enough, getline(3) will realloc(3) memory, and prefixes of the password will be laying around in some deallocated memory. See the getpass(3) manual page for more details, and especially the commit that marked it as deprecated, which links to a long discussion in the linux-man@ mailing list. So, readpassphrase(3bsd) is preferrable, which is provided by libbsd on GNU systems. However, using readpassphrase(3) directly is a bit verbose, so we can write our own wrapper with a simpler interface similar to that of getpass(3). One of the benefits of writing our own interface around readpassphrase(3) is that we can hide there any checks that should be done always and which would be error-prone to repeat every time. For example, check that there was no truncation in the password. Also, use malloc(3) to get the buffer, instead of using a global buffer. We're not using a multithreaded program (and it wouldn't make sense to do so), but it's nice to know that the visibility of our passwords is as limited as possible. erase_pass() is a clean-up function that handles all clean-up correctly, including zeroing the entire buffer, and then free(3)ing the memory. By using [[gnu::malloc(erase_pass)]], we make sure that we don't leak the buffers in any case, since the compiler will be able to enforce clean up. Link: <https://git.kernel.org/pub/scm/docs/man-pages/man-pages.git/commit?id=7ca189099d73bde954eed2d7fc21732bcc8ddc6b> Reported-by: Christian Göttsche <cgzones@googlemail.com> Signed-off-by: Alejandro Colomar <alx@kernel.org>
getpass(3) is broken in all implementations; in some, more than others, but somewhat broken in all of them. Check the immediate previous commit, which added the functions, for more details. Check also the Linux man-pages commit that marked it as deprecated, for more details: 7ca189099d73bde954eed2d7fc21732bcc8ddc6b. Link: <https://git.kernel.org/pub/scm/docs/man-pages/man-pages.git/commit?id=7ca189099d73bde954eed2d7fc21732bcc8ddc6b> Reported-by: Christian Göttsche <cgzones@googlemail.com> Signed-off-by: Alejandro Colomar <alx@kernel.org>
Clang doesn't implement this attribute and reports an error. Work around it by hiding it in a macro that will be empty in clang. Reported-by: Christian Göttsche <cgzones@googlemail.com> Signed-off-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Guillem Jover <guillem@hadrons.org> Signed-off-by: Alejandro Colomar <alx@kernel.org>
Rebase to master |
1abcebf
to
a04f230
Compare
Changes: reword caveats. calling erase_pass() twice is actually much worse than calling free(3) twice. It's calling memset(3) on freed memory. That's critical undefined behavior. |
I'm happy with the patch set now. If it passes the autotests, please review again. |
LGTM. Thanks for the patches! @hallyn any opinion before I merge it? |
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
*/ | ||
|
||
#include <config.h> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not any of the highlighted, but on autotools-based projects that's required yes, so that any of the checks performed by configure apply here, including extensions such as LFS support and similar.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not any of the highlighted,
I forgot to CC you. Good that you were notified anyway :)
but on autotools-based projects that's required yes, so that any of the checks performed by configure apply here, including extensions such as LFS support and similar.
Thanks!
It was a bit unintuitive to me that I'd need to include a header if I wan't using any of its definitions (since the build system usually finds the location of libbsd headers in projects I use, and then it's transparent to me; you can guess I don't use autotools :p).
Moving this forward to stop blocking you from other work you are doing. Thanks for your hard work! |
Thanks! I'll rebase the currently-open PRs. Cheers, Alex |
I still haven't added autoconf code to add the libbsd dependency, since I don't have much experience in using autoconf. If someone wants to help with that, please do :) Otherwise, gimme some time to do that.
I also reopened an old thread in the libc-alpha@ mailing list to discuss the possible addition of readpassphrase(3) to glibc (and also discuss the agetpass(3) interface, in case they want to add it too).