Authenticate a User.

Authenticate a User.

Post by hackkaus » Fri, 02 Dec 2005 15:51:15


Hello,

I am working on a project that needs to authenticate the user. I am not
sure what all ways should I look for. I am planning to make it run on
many of the unix like OS (say: Solaris, MacOSX, Linux, freeBSD). So it
will be really helpful if some one can tell me what all are the best
ways to authenticate on various OS.

I am right now looking for PAM authentication on LInux.


-- Hackkkaush
 
 
 

Authenticate a User.

Post by Kasper Dup » Fri, 02 Dec 2005 17:06:26


You could use getpwnam to lookup all the information related
to a user name. Next you may use crypt to verify the password.
I think that is the most portable, but on Linux using pam may
be a better way. Take a look on these links:

http://www.yqcomputer.com/ ~kasperd/comp.os.linux.development.faq.html#crypt
http://www.yqcomputer.com/ ~kasperd/comp.os.linux.development.faq.html#homedir

--
Kasper Dupont
Note to self: Don't try to allocate
256000 pages with GFP_KERNEL on x86.

 
 
 

Authenticate a User.

Post by Lars Kello » Fri, 02 Dec 2005 22:04:06

> You could use getpwnam to lookup all the information related

Using 'crypt' to validate passwords is a bad, nonportable idea that
will only get you into trouble. What if the system is using LDAP bind
authentication or Kerberos? Then the crypted password isn't ven
*available* to your application.

Similarly, using getpwnam to obtain information about users isn't
terribly flexible. It will give you information about *system* users,
but what if the user wants to use a different source of information?
You also get very little information about *authorization* -- what if
only users listed in /etc/myapplication.users should have access to your
code?

All this is why using a system such as PAM or SASL or something makes a
lot more sense.

-- Lars

--
Lars Kellogg-Stedman < XXXX@XXXXX.COM >
This email address will expire on 2005-11-23.
 
 
 

Authenticate a User.

Post by Lew Pitche » Fri, 02 Dec 2005 22:28:41

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1



First off, realize that PAM authentication is not supported in all distributions
of Linux, so while PAM may be a consideration, it isn't the whole answer.

Now, you should also realize that there are few 'user authentication' hooks that
are common to all Unix-ish OS. In fact, the only one that is, for certain,
supported in /all/ Unix is the POSIX/SUS getpwent()/crypt() APIs.

You are, of course, welcome to implement your logic with whatever APIs you wish.
Just realize that the official, supported, universal API is getpwent() and
crypt(). If you use anything else, you will have to include
platform/implementation/distribution specific code in your project, and have
some way of configuring your project to select between the authentication methods.


- --
Lew Pitcher
IT Specialist, Enterprise Data Systems,
Enterprise Technology Solutions, TD Bank Financial Group

(Opinions expressed are my own, not my employers')
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (MingW32)

iD8DBQFDjvqJagVFX4UWr64RAtPMAJ9nQYCG5LbK0lCeR2g3Yo6V2hDmJACglmVs
DuerE9eQJI51l6qPU8B/wKA=
=cTmt
-----END PGP SIGNATURE-----
 
 
 

Authenticate a User.

Post by Kasper Dup » Sat, 03 Dec 2005 05:07:47


[...]

getpwnam and crypt are specified by Posix, PAM is not.

--
Kasper Dupont
Note to self: Don't try to allocate
256000 pages with GFP_KERNEL on x86.
 
 
 

Authenticate a User.

Post by Lars Kello » Sat, 03 Dec 2005 06:30:52

> getpwnam and crypt are specified by Posix, PAM is not.

Nor is SASL, but they'll still provide you with a lot more flexibility.
In fact, in many cases they'll work when crypt won't. Using kerberos?
Too bad. There are no crypted passwords available. Using LDAP bind
authentication? Well, there are password hashes out there, but they're
probably not visible to the client. Using winbind? Etc.

Again, if your target user is working in a small environment with only a
few users, there's a good chance a crypt-based solution will work. More
power to you.

In a larger environment, your code will break, and because you're not
using a modular authentication mechanism it won't be fixable without
patching your code.

-- Lars

--
Lars Kellogg-Stedman < XXXX@XXXXX.COM >
This email address will expire on 2005-11-23.
 
 
 

Authenticate a User.

Post by hackkaus » Sat, 03 Dec 2005 22:15:14

Thanks folks,

It looks like PAM and getpwent()/crypt() got the maximum votes, I will
keep it configurable, so user can set whatever he prefers. Will provide
getpwent()/crypt() in default config, and in conf he can change it over
to PAM if he likes. Does this sound good to everyone??

One more thing, the utility I am working on is like remote access, so
the client is on different machine. Right now everything will go into
plain text, except password, so I am planning to crypt it first and
then send accross the network. I think for this the best approach will
be send back the salt from the server to the client, crypt it at the
client using that salt, and then send the crypted one to server from
client. Let me know if you have some comments.

Thanks.
 
 
 

Authenticate a User.

Post by Ms Rullg » Sun, 04 Dec 2005 03:53:20

"hackkaush" < XXXX@XXXXX.COM > writes:


That sounds reasonable, provided you implement in a way that makes
adding more authentication methods later easy. If you one day need to
authenticate using Kerberos, adding that functionality should not
require major changes to the code.


No good. In fact, no better than sending the password as plain text.
An attacker can simply sniff the encrypted password off the wire, and
send that when challenged. He won't find out the password, but he
will be able to gain access. To avoid a replay attack like this, you
must use a method where the salt changes each time.

--
Ms Rullgd
XXXX@XXXXX.COM
 
 
 

Authenticate a User.

Post by hackkaus » Sun, 04 Dec 2005 14:49:18

hey,

The passwd structure returned by 'getpwnam' gives 'x' in pw_passwd, and
that is probabily it does not take care of shadow, well I am not sure.

About crypt, if I take first 2 characters of the password hash stored
in the shadow file as salt, and crypt() the clear text password using
this salt, it is not the same as in the shodow file.

I hope it does not sound very lame.

Now I am planning to add ssl support for the communication between
server and client, any comments. It will be very helpful if someone can
send me some good doc or ebook on this. Whats the difference between
using ssl or tls? what is better? and what do you guys suggests??

Thanks
 
 
 

Authenticate a User.

Post by hackkaus » Sun, 04 Dec 2005 14:49:34

hey,

The passwd structure returned by 'getpwnam' gives 'x' in pw_passwd, and
that is probabily it does not take care of shadow, well I am not sure.

About crypt, if I take first 2 characters of the password hash stored
in the shadow file as salt, and crypt() the clear text password using
this salt, it is not the same as in the shodow file.

I hope it does not sound very lame.

Now I am planning to add ssl support for the communication between
server and client, any comments. It will be very helpful if someone can
send me some good doc or ebook on this. Whats the difference between
using ssl or tls? what is better? and what do you guys suggests??

Thanks
 
 
 

Authenticate a User.

Post by Kasper Dup » Sun, 04 Dec 2005 17:45:11


Sounds good, but remember to do it in such a way that it will
still compile and run using getpwent+crypt if the PAM libraries
are not available at compile time or run time. If you are using
autotools you could use something like: ./configure --with-pam
to enable PAM support in the program.


That is worse than sending password in cleartext. You do
prevent the protocol from leaking the password, but the
client may be able to authenticate without even knowing the
password. All the client needs to know is the password field
which in some configurations are world readable.

A solution is to let the server have a secret key and let
the client know the public key. Use this keypair to establish
shared keys for encryption and message authentication codes.
Once such keys are in place you may send the password over
the secured connection.

Use one of the recognized protocols for this key exchange,
because if you try to come up with one yourself you are
likely to run into one of the many subtle ways to do it
insecurely.

--
Kasper Dupont
Note to self: Don't try to allocate
256000 pages with GFP_KERNEL on x86.
 
 
 

Authenticate a User.

Post by Kasper Dup » Sun, 04 Dec 2005 17:55:53


It is no surprise to get an x in this field when the program
is not running as root. However it does come as a surprise to
me that it does not even handle shadow passwords when running
as root. That means the code supposed to be the most portable
does not work on most Linux systems. I'd say this is a bug in
getpwnam.

In that case my suggestion is to look on the source of some
of the existing programs doing authentication. login and xlock
both have to verify passwords, and they are AFAIK fairly
portable. (But somehow I fear that they get that portability
by having a long list of #ifdef directives.)


That is because the salt may be longer than 2 characters.
Just give the full password field as salt argument to crypt,
then crypt will be able to figure out how much of it to use.
Didn't I give you a link demonstrating this?


That sounds like a good idea.

--
Kasper Dupont
Note to self: Don't try to allocate
256000 pages with GFP_KERNEL on x86.
 
 
 

Authenticate a User.

Post by Lars Kello » Sun, 04 Dec 2005 23:26:52

> It is no surprise to get an x in this field when the program

This is the point I have been trying to get across. You *cannot* depend
on getpwnam() + crypt for password information. getpwnam() returns
entries from /etc/passwd, which on most modern systems doesn't actually
contain crypted passwords.

If you want to support shadow passwords, take a look at the "Linux
shadow password HOWTO", part of the Linux Documentation Project:

http://www.yqcomputer.com/

In particular:

http://www.yqcomputer.com/

Using something like PAM means you get a single, consistent interface to
work with regardless of what the system is using for authentication.
It's *not* available everywhere, but it's available on Linux, OS X,
Solaris, FreeBSD, NetBSD, and elsewhere.

Take a look at 'auth.c' from the OpenSSH source -- this has support for
plain getpwnam(), getpwnam() + shadow passwords, and pam.


Well, maybe. This is true if you're using the MD5 version of crypt,
which is triggered if you pass it a salt starting with '$1$', in which
case the salt can be up to eight characters.

Non-md5 passwords only have a two-character salt.

As you mentioned, using the original password as a salt will always do
the right thing.

-- Lars

--
Lars Kellogg-Stedman < XXXX@XXXXX.COM >
This email address will expire on 2005-11-23.
 
 
 

Authenticate a User.

Post by Kasper Dup » Mon, 05 Dec 2005 10:53:29


I believe the correct solution would be that getpwnam returned
the information from /etc/shadow on systems where that is
supported. I don't have access to the posix standard, but if
it makes any sense, then the way getpwnam is currently
implemented on Linux couldn't be compliant.


But an application intended to be portable cannot rely on pam
being present.


That is why I said the salt *may* be longer. It is not always
the case, but if it fails when you use only the first two chars,
then a longer salt is obviously a possible explanation. Many
systems now use MD5 based passwords by default, which always use
more than two chars in the salt.


DES based passwords only have a two character salt. Currently I
only know about DES based and MD5 based passwords, but in the
future others may be introduced which are most likely going to
use a longer salt just like MD5. The number between the first
two $ signs is used to indicate what kind of algorithm was used.
Maybe some day $2$ in the start of the string will be used to
indicate SHA512 based passwords. And only crypt would need to be
changed in order to support that as well (though you would
probably want to change the password change program as well to
generate passwords using the new kind of salt).


Which is why I advice doing it that way.

--
Kasper Dupont
Note to self: Don't try to allocate
256000 pages with GFP_KERNEL on x86.
 
 
 

Authenticate a User.

Post by Ms Rullg » Mon, 05 Dec 2005 21:39:38

Kasper Dupont < XXXX@XXXXX.COM > writes:



The standard doesn't require the password to be returned at all:

The <pwd.h> header shall provide a definition for struct passwd,
which shall include at least the following members:

char *pw_name User's login name.
uid_t pw_uid Numerical user ID.
gid_t pw_gid Numerical group ID.
char *pw_dir Initial working directory.
char *pw_shell Program to use as shell.

--
Ms Rullgd
XXXX@XXXXX.COM