GNOME Bugzilla – Bug 756315
[PATCH] Add crypt() binding to Posix VAPI
Last modified: 2015-10-27 16:29:39 UTC
Created attachment 312975 [details] [review] Patch to add crypt() to Posix VAPI Example program that reads a password typed in at the terminal and prints out the crypt() salt and hash as used in /etc/shadow The salt is 16 characters long in base64 for SHA-512: void main (string[] args) { var random_numbers = new uchar[20]; for (int a = 0; a < 20; a++) { random_numbers[a] = (uchar)Random.next_int(); } string salt = Base64.encode (random_numbers); try { salt = /\+/.replace( salt, -1, 0, "." ); } catch { } salt = salt[0:16]; salt = "$6$" + salt; Posix.getpass( "Enter password: " ); print (Posix.crypt( "test", salt ) + "\n"); } Compile with: valac --pkg posix -X -lcrypt -X -D_XOPEN_SOURCE A feature test macro, _XOPEN_SOURCE, needs to be set for glibc to expose the function definition. Other C libraries are similar, e.g musl requires _XOPEN_SOURCE or _GNU_SOURCE or _BSD_SOURCE. This is why the binding has been marked as experimental. glibc also requires crypt to be passed to the linker with -X -lcrypt
The example program should be: void main (string[] args) { var random_numbers = new uchar[20]; for (int a = 0; a < 20; a++) { random_numbers[a] = (uchar)Random.next_int(); } string salt = Base64.encode (random_numbers); try { salt = /\+/.replace( salt, -1, 0, "." ); } catch { } salt = salt[0:16]; salt = "$6$" + salt; string password = Posix.getpass( "Enter password: " ); print (Posix.crypt( password, salt ) + "\n"); } The original example had the password hard coded.
Thanks. It's not necessary to mark the binding experimental, I don't think it will be changed anyway. But why has it unowned return?
Created attachment 314235 [details] [review] Add binding for crypt() and deprecated getpass() in Posix VAPI This second version of the patch removes the experimental flag from crypt() and deprecates getpass(). getpass() has been deprecated since POSIX.2. See: http://pubs.opengroup.org/onlinepubs/7908799/xsh/getpass.html http://man7.org/linux/man-pages/man3/getpass.3.html
The reason crypt() is unowned return is from the POSIX standard[1]: "The return value of crypt() points to static data that is overwritten by each call." This must be the main reason the function is not threadsafe. It is similar for getpass() [1] - http://pubs.opengroup.org/onlinepubs/9699919799/functions/crypt.html
commit 33fb6fb5b719e9d64968ea87e0b19fdfab313fd6 Author: Al Thomas <astavale@yahoo.co.uk> Date: Tue Oct 27 17:28:36 2015 +0100 posix: add crypt(), deprecate getpass() Fixes bug 756315 This problem has been fixed in the unstable development version. The fix will be available in the next major software release. You may need to upgrade your Linux distribution to obtain that newer version.