"no such user" tells the client that the user ID isn't valid and,
therefore, that it needn't bother trying to do password cracking for
that user ID; just saying that the authentication failed dosn't give
them that hint.
This resolves the third problem in Include Security issue F11: [libpcap]
Remote Packet Capture Daemon Multiple Authentication Improvements.
The Windows LogonUser() API returns ERROR_LOGON_FAILURE for both cases,
so the Windows code doesn't have this issue. Just return the same
"Authentication failed" message on Windows to the user.
For various authentication failures *other* than "no such user" and
"password not valid", log a message, as there's a problem that may need
debugging. We don't need to tell the end user what the problem is, as
they may not bother reporting it and, even if they do, they may not give
the full error message.
* stop trying to log in with a given user name and move on
* to another user name.
*/
* stop trying to log in with a given user name and move on
* to another user name.
*/
+ char errmsgbuf[PCAP_ERRBUF_SIZE]; // buffer for errors to log
+
if (LogonUser(username, ".", password, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &Token) == 0)
{
if (LogonUser(username, ".", password, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &Token) == 0)
{
- pcap_fmt_errmsg_for_win32_err(errbuf, PCAP_ERRBUF_SIZE,
- GetLastError(), "LogonUser() failed");
+ snprintf(errbuf, PCAP_ERRBUF_SIZE, "Authentication failed");
+ error = GetLastError();
+ if (error != ERROR_LOGON_FAILURE)
+ {
+ // Some error other than an authentication error;
+ // log it.
+ pcap_fmt_errmsg_for_win32_err(errmsgbuf,
+ PCAP_ERRBUF_SIZE, error, "LogonUser() failed");
+ rpcapd_log(LOGPRIO_ERROR, "%s", errmsgbuf);
+ }
// I didn't test it.
if (ImpersonateLoggedOnUser(Token) == 0)
{
// I didn't test it.
if (ImpersonateLoggedOnUser(Token) == 0)
{
- pcap_fmt_errmsg_for_win32_err(errbuf, PCAP_ERRBUF_SIZE,
+ snprintf(errbuf, PCAP_ERRBUF_SIZE, "Authentication failed");
+ pcap_fmt_errmsg_for_win32_err(errmsgbuf, PCAP_ERRBUF_SIZE,
GetLastError(), "ImpersonateLoggedOnUser() failed");
GetLastError(), "ImpersonateLoggedOnUser() failed");
+ rpcapd_log(LOGPRIO_ERROR, "%s", errmsgbuf);
CloseHandle(Token);
return -1;
}
CloseHandle(Token);
return -1;
}
* only password database or some other authentication mechanism,
* behind its API.
*/
* only password database or some other authentication mechanism,
* behind its API.
*/
struct passwd *user;
char *user_password;
#ifdef HAVE_GETSPNAM
struct passwd *user;
char *user_password;
#ifdef HAVE_GETSPNAM
// This call is needed to get the uid
if ((user = getpwnam(username)) == NULL)
{
// This call is needed to get the uid
if ((user = getpwnam(username)) == NULL)
{
- snprintf(errbuf, PCAP_ERRBUF_SIZE, "Authentication failed: user name or password incorrect");
+ snprintf(errbuf, PCAP_ERRBUF_SIZE, "Authentication failed");
// This call is needed to get the password; otherwise 'x' is returned
if ((usersp = getspnam(username)) == NULL)
{
// This call is needed to get the password; otherwise 'x' is returned
if ((usersp = getspnam(username)) == NULL)
{
- snprintf(errbuf, PCAP_ERRBUF_SIZE, "Authentication failed: user name or password incorrect");
+ snprintf(errbuf, PCAP_ERRBUF_SIZE, "Authentication failed");
return -1;
}
user_password = usersp->sp_pwdp;
return -1;
}
user_password = usersp->sp_pwdp;
user_password = user->pw_passwd;
#endif
user_password = user->pw_passwd;
#endif
+ //
+ // The Single UNIX Specification says that if crypt() fails it
+ // sets errno, but some implementatons that haven't been run
+ // through the SUS test suite might not do so.
+ //
+ errno = 0;
crypt_password = crypt(password, user_password);
if (crypt_password == NULL)
{
crypt_password = crypt(password, user_password);
if (crypt_password == NULL)
{
snprintf(errbuf, PCAP_ERRBUF_SIZE, "Authentication failed");
snprintf(errbuf, PCAP_ERRBUF_SIZE, "Authentication failed");
+ if (error == 0)
+ {
+ // It didn't set errno.
+ rpcapd_log(LOGPRIO_ERROR, "crypt() failed");
+ }
+ else
+ {
+ rpcapd_log(LOGPRIO_ERROR, "crypt() failed: %s",
+ strerror(error));
+ }
return -1;
}
if (strcmp(user_password, crypt_password) != 0)
{
return -1;
}
if (strcmp(user_password, crypt_password) != 0)
{
- snprintf(errbuf, PCAP_ERRBUF_SIZE, "Authentication failed: user name or password incorrect");
+ snprintf(errbuf, PCAP_ERRBUF_SIZE, "Authentication failed");
return -1;
}
if (setuid(user->pw_uid))
{
return -1;
}
if (setuid(user->pw_uid))
{
pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ error, "setuid");
+ rpcapd_log(LOGPRIO_ERROR, "setuid() failed: %s",
+ strerror(error));
return -1;
}
/* if (setgid(user->pw_gid))
{
return -1;
}
/* if (setgid(user->pw_gid))
{
pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
errno, "setgid");
pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
errno, "setgid");
+ rpcapd_log(LOGPRIO_ERROR, "setgid() failed: %s",
+ strerror(error));