

Retiring crypt - zdw
http://www.tedunangst.com/flak/post/retiring-crypt

======
tptacek
_Ducking_

The printf("%s %s", foo(), foo()) problem is unusual for crypt() --- but it
isn't for other functions that return points to global static memory,
inet_ntoa() in particular (you often want to print both source and destination
addresses). To get around this, I used to have a preloaded inet_ntoa that
alternated between two global static buffers. :)

~~~
JoachimSchipper
Preloading a version that alternates between two buffers is clearly Wrong, but
I'm not sure what the right solution is - do you/does anyone have a pattern
that they find works well for them?

Our codebase has quite a few functions like inet_ntoa():

    
    
        /* returns ptr. to internal static storage */
        const char *type_to_str(const Type *type);
    

You could pass an explicit argument, but that's pretty ugly:

    
    
        /* Explicit buffer argument */
        char msg_buf1[256], msg_buf2[256], msg_buf3[256], ..., msg_buf16[256];
        char *type_to_str(char *buf_to_use, size_t buf_size, const Type *type)
    

Alternatively, you could give C99 a workout and abuse compound literals as
anonymous storage:

    
    
        #include <stdio.h>
        
        struct foo {
            int      bar;   
        };  
        
        #define FOO_TO_STR_SIZE 256
        
        #define foo_to_str(foo) \
            foo_to_str_((char [FOO_TO_STR_SIZE]){ 0 }, FOO_TO_STR_SIZE, (foo))
    
        /* Implementation detail */  
        __attribute__((nonnull))
        static char *foo_to_str_(char *buf_to_use, size_t size,
            const struct foo *foo)
        {   
            (void)snprintf(buf_to_use, size, "%d", foo->bar);
        
            return buf_to_use;
        }
        
        int main(void)
        {
            const struct foo foo = {
                .bar = 42
            },               foo2 = {
                .bar = 43
            };
            printf("%s %s\n", foo_to_str(&foo),
                foo_to_str(&foo2));
        
            return 0;
        }   
    

(Warning: this is probably too clever. Note that you need the explicit size
argument if you offer a library, or you risk your callers using a different
FOO_TO_STR_SIZE than you do. There is probably a very minor performance
penalty to this solution as the caller must, in general, completely initialize
the string. Note the gcc warnings about compound literals in C++ - see
[https://gcc.gnu.org/onlinedocs/gcc/Compound-
Literals.html](https://gcc.gnu.org/onlinedocs/gcc/Compound-Literals.html) for
a discussion.)

~~~
tptacek
It's morally wrong, but since you usually only ever want to print two IP
addresses, it feels so right. In any case: it can't break otherwise-correct
code.

------
zaroth
The PHC is defining a standard API which works with all the proposed
algorithms as part of the contest. There's a lot that a proper password
hashing API can provide and be secure by default. The PHC mailing list has
pretty extensive discussion on this topic.

[1] -
[http://dir.gmane.org/gmane.comp.security.phc](http://dir.gmane.org/gmane.comp.security.phc)

------
TazeTSchnitzel
PHP has a pretty nice _password_hash_ API, would be nice if other languages
copied it: [http://php.net/password_hash](http://php.net/password_hash)

    
    
      string password_hash ( string $password , integer $algo [, array $options ] )
      boolean password_verify ( string $password , string $hash )
      boolean password_needs_rehash ( string $hash , integer $algo [, array $options ] )

------
aidenn0
Where I work we still have many solaris machines and our logins are managed
via NIS. Is there a hashing function that is supported for logins on solaris,
linux and BSD that we can use other than the DES based one?

~~~
rwg
Solaris 9+, recentish Linux, and recentish BSD should all support algorithm
$1$ (MD5) at an absolute minimum. Depending on OS versions, you might also be
able to choose from $2a$ (Blowfish), $5$ (SHA-256), and $6$ (SHA-512). On
Solaris, the list of supported algorithms is in /etc/security/crypt.conf. "man
3 crypt" might tell you what's supported on your Linux and BSD machines.

For NIS, you'd need to ensure that every machine that touches passwords via
NIS is configured to use the same algorithm when users change passwords. On
Solaris, just configure CRYPT_* in /etc/security/policy.conf the same on every
machine. (See the policy.conf man page — in short, you want to change the
default algorithm to 1 [or whatever] and set __unix__ to be deprecated.) On
Linux and *BSD, how you do it depends on the distro/version.

Fun fact about changing passwords in NIS: When a yppasswd client contacts
rpc.yppasswdd to change a user's password, the user's new password is sent
crypt()ed, but the user's old password is sent in the clear.

------
coreymgilmore
Just Use Bcrypt

[http://codahale.com/how-to-safely-store-a-password/](http://codahale.com/how-
to-safely-store-a-password/)

~~~
vog
Could you elaborate on that? The article explicitly mentions bcrypt, so what's
the point you are trying to make?

~~~
mentat
I would guess he was trying to mock the meme that everyone says whenever the
question of storing passwords comes up here.

