libpam: Block sshd's INCORRECT password to AAA server (#10029)
Why I did it sshd overrides user password with a bad one, when pre-auth fails. Refer PR #9123 for more details How I did it Manual cherry pick of PR #9123 How to verify it Pick a user alias that has not logged into the switch yet Add this alias to /etc/tacplus_user Attempt to login as that user Look for the error message in /var/log/syslog e.g. "Feb 18 19:16:41.592191 sonic ERR sshd[5233]: auth fail: Password incorrect. user: user_xyz"
This commit is contained in:
parent
7910108fd8
commit
ca7d73049d
115
src/tacacs/pam/0006-handle-bad-password-set-by-sshd.patch
Normal file
115
src/tacacs/pam/0006-handle-bad-password-set-by-sshd.patch
Normal file
@ -0,0 +1,115 @@
|
||||
From 854d3f9cae530cea6b4c12481759bd5cb139259f Mon Sep 17 00:00:00 2001
|
||||
From: Renuka Manavalan <remanava@microsoft.com>
|
||||
Date: Fri, 18 Feb 2022 18:34:03 +0000
|
||||
Subject: [PATCH] handle bad password set by sshd
|
||||
|
||||
---
|
||||
pam_tacplus.c | 7 +++++++
|
||||
support.c | 37 +++++++++++++++++++++++++++++++++++++
|
||||
support.h | 1 +
|
||||
tacc.c | 4 ++--
|
||||
4 files changed, 47 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/pam_tacplus.c b/pam_tacplus.c
|
||||
index 38e2a70..bf06519 100644
|
||||
--- a/pam_tacplus.c
|
||||
+++ b/pam_tacplus.c
|
||||
@@ -251,6 +251,13 @@ int pam_sm_authenticate (pam_handle_t * pamh, int flags,
|
||||
return PAM_CRED_INSUFFICIENT;
|
||||
}
|
||||
|
||||
+ if (validate_not_sshd_bad_pass(pass) != PAM_SUCCESS) {
|
||||
+ syslog(LOG_LOCAL0|LOG_ERR, "auth fail: Password incorrect. user: %s", user);
|
||||
+ memset(pass, 0, strlen (pass));
|
||||
+ free(pass);
|
||||
+ return PAM_AUTH_ERR;
|
||||
+ }
|
||||
+
|
||||
retval = pam_set_item (pamh, PAM_AUTHTOK, pass);
|
||||
if (retval != PAM_SUCCESS) {
|
||||
_pam_log(LOG_ERR, "unable to set password");
|
||||
diff --git a/support.c b/support.c
|
||||
index 7c00618..a34d061 100644
|
||||
--- a/support.c
|
||||
+++ b/support.c
|
||||
@@ -106,6 +106,43 @@ int converse(pam_handle_t * pamh, int nargs, const struct pam_message *message,
|
||||
return retval;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Ref: From <https://groups.google.com/g/mailing.unix.openssh-dev/c/ViHvtciKYh0>
|
||||
+ * For future archive searchers:
|
||||
+ * > Why does OpenSSH replaces the password entered by the user with the
|
||||
+ * > bad password - "\b\n\r\177INCORRECT
|
||||
+ *
|
||||
+ * There are some situations where sshd determines a user can't log in.
|
||||
+ * Typical samples of that are DenyUsers or PermitRootLogin.
|
||||
+ * In those cases sshd *still* calls PAM, so that delays set by it are
|
||||
+ * still performed to the user (without leaking info about accounts
|
||||
+ * existing, disabled, etc.). But in order to ensure it can't succeed,
|
||||
+ * replaces the password with that impossible one.
|
||||
+ *
|
||||
+ */
|
||||
+int validate_not_sshd_bad_pass(const char *pass)
|
||||
+{
|
||||
+ const char *SSHD_BAD_PASS = "\010\012\015\177INCORRECT";
|
||||
+ const int SSHD_BAD_PASS_LEN = strlen(SSHD_BAD_PASS);
|
||||
+
|
||||
+ int len = strlen(pass);
|
||||
+ const char *p = pass;
|
||||
+
|
||||
+ if (len == 0)
|
||||
+ return PAM_SUCCESS;
|
||||
+
|
||||
+ while (len > 0) {
|
||||
+ int l = len < SSHD_BAD_PASS_LEN ? len : SSHD_BAD_PASS_LEN;
|
||||
+
|
||||
+ if (strncmp(p, SSHD_BAD_PASS, l) != 0)
|
||||
+ return PAM_SUCCESS;
|
||||
+
|
||||
+ len -= l;
|
||||
+ p += l;
|
||||
+ }
|
||||
+ return PAM_AUTH_ERR;
|
||||
+}
|
||||
+
|
||||
/* stolen from pam_stress */
|
||||
int tacacs_get_password (pam_handle_t * pamh, int flags
|
||||
,int ctrl, char **password) {
|
||||
diff --git a/support.h b/support.h
|
||||
index 9cbd040..d7845d3 100644
|
||||
--- a/support.h
|
||||
+++ b/support.h
|
||||
@@ -41,6 +41,7 @@ extern char tac_prompt[64];
|
||||
int _pam_parse (int, const char **);
|
||||
unsigned long _resolve_name (char *);
|
||||
unsigned long _getserveraddr (char *serv);
|
||||
+int validate_not_sshd_bad_pass(const char *pass);
|
||||
int tacacs_get_password (pam_handle_t *, int, int, char **);
|
||||
int converse (pam_handle_t *, int, const struct pam_message *, struct pam_response **);
|
||||
void _pam_log (int, const char *, ...);
|
||||
diff --git a/tacc.c b/tacc.c
|
||||
index fcc7d8c..bf0f2a3 100644
|
||||
--- a/tacc.c
|
||||
+++ b/tacc.c
|
||||
@@ -181,7 +181,7 @@ int main(int argc, char **argv) {
|
||||
break;
|
||||
case 'L':
|
||||
// tac_login is a global variable initialized in libtac
|
||||
- bzero(tac_login, sizeof(tac_login));
|
||||
+ memset(tac_login, 0, sizeof(tac_login));
|
||||
strncpy(tac_login, optarg, sizeof(tac_login) - 1);
|
||||
break;
|
||||
case 'p':
|
||||
@@ -312,7 +312,7 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
|
||||
/* we no longer need the password in our address space */
|
||||
- bzero(pass, strlen(pass));
|
||||
+ memset(pass, 0, strlen(pass));
|
||||
pass = NULL;
|
||||
|
||||
if (do_account) {
|
||||
--
|
||||
2.17.1
|
||||
|
@ -19,6 +19,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% :
|
||||
git apply ../0003-Obfuscate-key-before-printing-to-syslog.patch
|
||||
git apply ../0004-management-vrf-support.patch
|
||||
git apply ../0005-pam-Modify-parsing-of-IP-address-and-port-number-to-.patch
|
||||
git apply ../0006-handle-bad-password-set-by-sshd.patch
|
||||
|
||||
dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) --admindir $(SONIC_DPKG_ADMINDIR)
|
||||
popd
|
||||
|
Reference in New Issue
Block a user