Bug 117 - OpenSSH second-guesses PAM
Summary: OpenSSH second-guesses PAM
Status: CLOSED FIXED
Alias: None
Product: Portable OpenSSH
Classification: Unclassified
Component: sshd (show other bugs)
Version: -current
Hardware: Other Linux
: P2 normal
Assignee: OpenSSH Bugzilla mailing list
URL:
Keywords: patch
Depends on:
Blocks:
 
Reported: 2002-02-15 09:56 AEDT by Andrew Bartlett
Modified: 2004-04-14 12:24 AEST (History)
0 users

See Also:


Attachments
Use supplied username in pam_start calls always (924 bytes, patch)
2003-03-10 11:57 AEDT, Damien Miller
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Andrew Bartlett 2002-02-15 09:56:23 AEDT
As I described in bug 114, OpenSSH makes assumptions about how PAM operates, and
denies it acess to potentially critical information about failed logins. 

This problem occurs if you want to use PAM to obtain a consistant audit history
across all system deamons - OpenSSH traditionally would not even start PAM, and
now starts it specifying 'NOUSER' as the login name.

I feel that the correct behaviour is to always call PAM.  There are two
particular reasons:  Firstly, it ensures that PAM gets to decide that a user is
invalid, and log it appropriatly.  OpenSSH can add its own checks to the top,
but the first decision should be with PAM.

The second is to prevent username guessing attacks - by always calling PAM the
system should always suffer the same timeouts/delays no matter the existance of
the attempted login.

Another (almost certainly less convincing) reason is that it would make it
easier for sombody to write an OpenSSH based deamon that didn't service logins -
like an authenticated proxy service that uses SSH for secure transport to the
firewall.  In this case the user almost certainly doesn't exist locally, but PAM
can still be useful for authenticaion.  (OK, so this is really oddball, but my
main concern is the first two reasons).
Comment 1 Damien Miller 2002-02-15 10:10:06 AEDT
> OpenSSH traditionally would not even start PAM, and
> now starts it specifying 'NOUSER' as the login name.

We have always used NOUSER, the recent patch just makes it consistent between
protocols 1 and 2.

> The second is to prevent username guessing attacks - by 
> always calling PAM the system should always suffer the 
> same timeouts/delays no matter the existance of the 
> attempted login.

I don't think this is the case: the auth code attempts 
all authentications with the fake username anyway, so 
this should not be an issue unless the PAM modules 
themselves are broken.

We rely on getpwnam() working in lots of places, so changing 
this would be a fair amount of work.
Comment 2 Darren J Moffat 2002-02-15 10:47:22 AEDT
There is nothing wrong with calling pam_set_item to set an item to NULL and in
fact there are modules on Solaris that do exactly that for PAM_AUTHTOK.

PAM on Solaris would not have syslogged the pam_set_item message that is 
described in bug 114

There is nothing wrong in having a syslog message for pam_set_item being
called with the item value as NULL, however since it is perfectly valid to do
so this should be a debug only syslog message and either the case being
reported had pam framework debugging enabled or there is a bug in the Linux PAM
framework library.

It is perfectly valid to pass NULL as the user into pam_start; pam_start
ultimately calls pam_set_item to setup the PAM_USER.  If the application does
that then it should use pam_get_item(pamh, PAM_USER, &user) to find out which
user was authenticated if pam_authenticate returned PAM_SUCCESS.

I would rather that OpenSSH passed NULL to pam_start than passing NOUSER.  There
could potentially be modules on the stack that will prompt for a user name
if PAM_USER is empty - this is perfectly valid PAM according to the XSSO spec
(which Linux PAM does not comply with - it has extended and embraced in an
incompatible way in some areas).
Passing the string "NOUSER" takes a way a valid username out of the namespace,
what if there really was a user called nouser (The user account for some 
subsystem called 'no' for example or someone called Neil Ouser) the
pam_authenticate call might actually succeed - this probably isn't what you were 
expecting to happen in this case.

PAM_USER == NULL means I the application don't know the user name, anything else
is taken to mean you the application are trying to authenticate the named user.

I believe the correct fix is for OpenSSH to pass NULL to pam_start when it
doesn't know the username and pass the username when it does.
Comment 3 Andrew Bartlett 2002-02-15 11:13:16 AEDT
The problem is that OpenSSH knows the username perfectly well at this stage.  It
just refuses to pass it on to PAM!

This means that PAM cannot log the fact that an invalid login was attempted -
which is my primary issue here.  I am doing some work on a product that is
hoping to use PAM to log all authenticaion failures in a consistant manner
across all system deamons.  

I see know reason why PAM cannot be told the truth, allowing this kind of thing
without ugly hacks to OpenSSH itself (the current way this is done).  

auth_sia_password() doesn't take a 'struct passwd' argument, why should PAM have
to?  (The bits of auth_pam_password() and auth_password() that deal with the
pw->uid feild should really be in a single function, elsewhere)
Comment 4 Frank Cusack 2002-04-16 23:27:08 AEST
sshd should definitely not be using 'NOUSER'.  The correct thing is to use
the username, regardless of whether (pw) exists.  I can't understand why
you would substitute the value 'NOUSER'.
Comment 5 Damien Miller 2002-04-17 11:07:30 AEST
You do see the username, auth2.c line 193-197:

    log("input_userauth_request: illegal user %s", user);
#ifdef USE_PAM
    start_pam("NOUSER");
#endif

We fake a username with PAM to mitigate timing attacks.
Comment 6 Frank Cusack 2002-04-17 17:54:07 AEST
Yes "YOU" see the username but PAM doesn't.  How about a comment in the
code about the timing attack you are trying to mitigate?

You are eliminating the possibility that sshd might want to authenticate
someone without a local account (requesting a non-login service?).

Also, I think this is counter-productive with PAM. PAM has it's own
ability to do this.
Comment 7 Damien Miller 2002-04-17 23:39:42 AEST
> You are eliminating the possibility that sshd might want to authenticate
> someone without a local account (requesting a non-login service?).

PAM shouldn't be abused to to be a getpw* replacement. Quoth
http://www.opengroup.org/tech/rfc/mirror-rfc/rfc86.0.txt:

] (c) We do not address the source of information obtained from the
] "`getXbyY()'" family of calls (e.g., `getpwnam()').
Comment 8 Andrew Bartlett 2002-04-18 00:37:13 AEST
While there are varying ideas on the interesting ways OpenSSH could be modified
for usage without login accounts (and I see some real usful ideas here actually)
this isn't the main issue.

OpenSSH should always forward the correct username to PAM.  Forwarding the
incorrect username achives nothing - and prevents PAM from logging 'attempted
login for user _____' in a consistant way across all system deamons.
Comment 9 Frank Cusack 2002-05-09 13:38:31 AEST
Forwarding a fake username also means there is an undocumented username
that has side effects caused by sshd; although all caps probably makes
this a non-concern, to me it still smacks of special names like COM.

This will be my last comment on the matter:

- You are not doing anything by using 'NOUSER', at least nothing I can
  figure out.  If this is to prevent some kind of attack, please add
  comments in the code.
- You *are* causing problems.  eg, my sshd w/ PAM uses a RADIUS backend.
  On my RADIUS server I get logs for 'NOUSER' failing.  I would like to
  know what the attempted username was, and I would like to get this from
  a central source (the RADIUS server).  I will admit, on the level of
  "problems" this is minor if 'NOUSER' actually prevents some attack.
- The protocol 1 code path does not call PAM at all for invalid users.
  This would be acceptable for the protocol 2 code path, and better than
  using 'NOUSER', but eliminate the possibility of non-login services.
Comment 10 Damien Miller 2003-03-10 11:57:08 AEDT
Created attachment 245 [details]
Use supplied username in pam_start calls always

Make sshd always use supplied username (even if it is invalid) in calls to PAM
Comment 11 Damien Miller 2003-03-10 12:17:41 AEDT
I'm still not sure whether supplying a bad username to PAM is a good idea, but
at least there is a patch that people can try timing attacks against.
Comment 12 Damien Miller 2003-05-14 10:26:20 AEST
Patch applied
Comment 13 Damien Miller 2004-04-14 12:24:18 AEST
Mass change of RESOLVED bugs to CLOSED