PAM with two-factor authorization enabled

38 views
Skip to first unread message

thunderliu

unread,
Aug 18, 2019, 4:00:18 AM8/18/19
to TigerVNC Developer Discussion
Hi guys,

I found that the Xvnc server in PAM mode will always fail with 2FA enabled, even for optional second factor. Here's the condition to repeat it:
  • TigerVNC server used in PAM mode (authentication with both username and password). Easiest way to do it is in inetd mode:
Xvnc -inetd -query localhost -once -SecurityTypes VeNCrypt,TLSPlain -PlainUsers=testusr1 -pam_service=login

  • CentOS 7.6 in an IDM environment, when the targeted user has 2FA enabled in the IDM system. The user can have only 2FA enabled or both 2FA+password enabled. If "password" is enabled then second factor is optional; but even in optional mode the authentication will still fail.

1.PNG


I spent some time on it, and found common/rfb/pam.c blindly send password if the prompt type is PAM_PROMPT_ECHO_OFF. So the password is sent twice and PAM doesn't like wrong second factor, even it can accept an empty one.

So here's a simple patch to work around this problem in optional 2FA case until we can get a full-fledged second factor input window.

diff --git a/common/rfb/pam.c b/common/rfb/pam.c
index cb067fd..15d9514 100644
--- a/common/rfb/pam.c
+++ b/common/rfb/pam.c
@@ -36,6 +36,7 @@ typedef struct
 {
   const char *username;
   const char *password;
+  int password_sent;
 } AuthData;
 
 #if defined(__sun)
@@ -65,7 +66,13 @@ static int pam_callback(int count, const struct pam_message **in,
       resp[i].resp = strdup(auth->username);
       break;
     case PAM_PROMPT_ECHO_OFF: /* Send Password */
-      resp[i].resp = strdup(auth->password);
+      if (auth->password_sent) {
+        /* Likely the second password which we don't support yet */
+        resp[i].resp = 0;
+      } else {
+        resp[i].resp = strdup(auth->password);
+        auth->password_sent = 1;
+      }
       break;
     default:
       free(resp);
@@ -81,7 +88,7 @@ static int pam_callback(int count, const struct pam_message **in,
 int do_pam_auth(const char *service, const char *username, const char *password)
 {
   int ret;
-  AuthData auth = { username, password };
+  AuthData auth = { username, password, 0 };
   struct pam_conv conv = {
     pam_callback,
     &auth

Hope this helps.


Pierre Ossman

unread,
Aug 21, 2019, 5:23:40 AM8/21/19
to thunderliu, TigerVNC Developer Discussion
On 18/08/2019 10:00, thunderliu wrote:
>
> I spent some time on it, and found common/rfb/pam.c blindly send password
> if the prompt type is PAM_PROMPT_ECHO_OFF. So the password is sent twice
> and PAM doesn't like wrong second factor, even it can accept an empty one.
>
> So here's a simple patch to work around this problem in *optional 2FA case *until
> we can get a full-fledged second factor input window.
>

Thank you for your patch, but I'm afraid I'm going to have to say no.

Trying to map a single password to the multiple possible prompts of PAM
is always going to be imperfect. Right now we're doing the same thing as
OpenSSH. Whilst this is still imperfect, it is at least an extremely
common method as OpenSSH is very widely deployed. Choosing a different
method is likely to cause more issues than it solves as it will not be
as widely tested.

Ideally someone implements an extension to VNC that allows multiple
prompts so that the entire PAM conversation can be sent to the user.

Regards
--
Pierre Ossman Software Development
Cendio AB https://cendio.com
Teknikringen 8 https://twitter.com/ThinLinc
583 30 Linköping https://facebook.com/ThinLinc
Phone: +46-13-214600

A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
Reply all
Reply to author
Forward
0 new messages