]> source.dussan.org Git - tigervnc.git/commitdiff
[Development] Implement *Plain security types on the server side and use
authorAdam Tkac <atkac@redhat.com>
Thu, 2 Sep 2010 14:13:24 +0000 (14:13 +0000)
committerAdam Tkac <atkac@redhat.com>
Thu, 2 Sep 2010 14:13:24 +0000 (14:13 +0000)
PAM for credential validation on UNIX.

git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@4128 3789f03b-4d11-0410-bbf8-ca57d06f2519

common/rfb/Makefile.am
common/rfb/SSecurityPlain.cxx
common/rfb/SSecurityPlain.h
common/rfb/Security.cxx
configure.ac

index 4e5bbd7f3349e7928e6c5a0f1395255ae905c202..9251e2fc12522f950d4e9c7af0f571884d05c714 100644 (file)
@@ -55,6 +55,11 @@ endif
 librfb_la_CPPFLAGS = -I$(top_srcdir)/common -I$(top_srcdir)/win
 librfb_la_LIBADD = @GNUTLS_LIBS@
 
+if HAVE_PAM
+librfb_la_SOURCES += UnixPasswordValidator.cxx UnixPasswordValidator.h pam.c pam.h
+librfb_la_LIBADD += $(PAM_LIBS)
+endif
+
 if INCLUDED_JPEG
 librfb_la_CPPFLAGS += -I$(top_srcdir)/common/jpeg -I$(top_builddir)/common/jpeg
 librfb_la_LIBADD += $(top_builddir)/common/jpeg/libjpeg.la
index 6d0c67e91dff0ab489b110b6ce9c8f0511f49e53..84ef099771055b490031c099dc595fd65cc21a75 100644 (file)
@@ -25,6 +25,9 @@
 #include <rfb/SConnection.h>
 #include <rfb/Exception.h>
 #include <rdr/InStream.h>
+#ifdef HAVE_PAM
+#include <rfb/UnixPasswordValidator.h>
+#endif
 
 using namespace rfb;
 
@@ -36,27 +39,33 @@ StringParameter PasswordValidator::plainUsers
 bool PasswordValidator::validUser(const char* username)
 {
   CharArray users(strDup(plainUsers.getValueStr())), user;
+
   while (users.buf) {
     strSplit(users.buf, ',', &user.buf, &users.buf);
 #ifdef WIN32
-    if(0==stricmp(user.buf, "*"))
+    if (0 == stricmp(user.buf, "*"))
          return true;
-    if(0==stricmp(user.buf, username))
+    if (0 == stricmp(user.buf, username))
          return true;
 #else
-    if(!strcmp (user.buf, "*"))
+    if (!strcmp(user.buf, "*"))
          return true;
-    if(!strcmp (user.buf, username))
+    if (!strcmp(user.buf, username))
          return true;
 #endif
   }
   return false;
 }
 
-SSecurityPlain::SSecurityPlain(PasswordValidator* _valid)
+SSecurityPlain::SSecurityPlain()
 {
-  valid=_valid;
-  state=0;
+#ifdef HAVE_PAM
+  valid = new UnixPasswordValidator();
+#else
+  valid = NULL;
+#endif
+
+  state = 0;
 }
 
 bool SSecurityPlain::processMsg(SConnection* sc)
@@ -66,32 +75,34 @@ bool SSecurityPlain::processMsg(SConnection* sc)
   char *uname;
   CharArray password;
 
-  if(state==0)
-  {
-    if(!is->checkNoWait(8))
+  if (!valid)
+    throw AuthFailureException("No password validator configured");
+
+  if (state == 0) {
+    if (!is->checkNoWait(8))
       return false;
-    ulen=is->readU32();
-    plen=is->readU32();
-    state=1;
+    ulen = is->readU32();
+    plen = is->readU32();
+    state = 1;
   }
-  if(state==1)
-  {
-    if(is->checkNoWait(ulen+plen+2))
+
+  if (state == 1) {
+    if (is->checkNoWait(ulen + plen + 2))
       return false;
-    state=2;
-    pw=new char[plen+1];
-    uname=new char[ulen+1];
+    state = 2;
+    pw = new char[plen + 1];
+    uname = new char[ulen + 1];
     username.replaceBuf(uname);
     password.replaceBuf(pw);
-    is->readBytes(uname,ulen);
-    is->readBytes(pw,plen);
-    pw[plen]=0;
-    uname[ulen]=0;
-    plen=0;
-    if(!valid->validate(sc,uname,pw))
-         throw AuthFailureException("invalid password or username");
-    return true;
+    is->readBytes(uname, ulen);
+    is->readBytes(pw, plen);
+    pw[plen] = 0;
+    uname[ulen] = 0;
+    plen = 0;
+    if (!valid->validate(sc, uname, pw))
+      throw AuthFailureException("invalid password or username");
   }
+
   return true;
 }
 
index f170bd5ba09f3d32bd7ef400676adcc73a12cec6..080fcd598f631b1714175c3233c2d420d34ce86c 100644 (file)
@@ -34,24 +34,25 @@ namespace rfb {
 
   class PasswordValidator {
   public:
-    // validate username / password combination
-       bool validate(SConnection* sc, const char *username, const char *password) { return validUser(username) ? validateInternal(sc, username, password) : false; };
-       static StringParameter plainUsers;
+    bool validate(SConnection* sc, const char *username, const char *password)
+      { return validUser(username) ? validateInternal(sc, username, password) : false; }
+    static StringParameter plainUsers;
+
   protected:
     virtual bool validateInternal(SConnection* sc, const char *username, const char *password)=0;
-       static bool validUser(const char* username);
+    static bool validUser(const char* username);
   };
 
   class SSecurityPlain : public SSecurity {
   public:
-    SSecurityPlain(PasswordValidator* valid);
+    SSecurityPlain();
     virtual bool processMsg(SConnection* sc);
-    virtual int getType() const {return secTypePlain;};
+    virtual int getType() const { return secTypePlain; };
     virtual const char* getUserName() const { return username.buf; }
 
   private:
     PasswordValidator* valid;
-    unsigned int ulen,plen,state;
+    unsigned int ulen, plen, state;
     CharArray username;
   };
 
index 874c346f335eb6caba71d810c4fca384b87ca5d8..2ea51fac63fb8b2bdadca64f5d6ca0c796bb0c40 100644 (file)
@@ -37,6 +37,7 @@
 #include <rfb/Security.h>
 #include <rfb/SSecurityNone.h>
 #include <rfb/SSecurityStack.h>
+#include <rfb/SSecurityPlain.h>
 #include <rfb/SSecurityVncAuth.h>
 #include <rfb/SSecurityVeNCrypt.h>
 #ifdef HAVE_GNUTLS
@@ -146,15 +147,20 @@ SSecurity* Security::GetSSecurity(U32 secType)
   case secTypeNone: return new SSecurityNone();
   case secTypeVncAuth: return new SSecurityVncAuth();
   case secTypeVeNCrypt: return new SSecurityVeNCrypt(this);
+  case secTypePlain: return new SSecurityPlain();
 #ifdef HAVE_GNUTLS
   case secTypeTLSNone:
     return new SSecurityStack(secTypeTLSNone, new SSecurityTLS(true));
   case secTypeTLSVnc:
     return new SSecurityStack(secTypeTLSVnc, new SSecurityTLS(true), new SSecurityVncAuth());
+  case secTypeTLSPlain:
+    return new SSecurityStack(secTypeTLSPlain, new SSecurityTLS(true), new SSecurityPlain());
   case secTypeX509None:
     return new SSecurityStack(secTypeX509None, new SSecurityTLS(false));
   case secTypeX509Vnc:
     return new SSecurityStack(secTypeX509None, new SSecurityTLS(false), new SSecurityVncAuth());
+  case secTypeX509Plain:
+    return new SSecurityStack(secTypeX509Plain, new SSecurityTLS(false), new SSecurityPlain());
 #endif
   }
 
index 5acd76275a6a09b7f68f6b7f165a5bb36362c243..c411f8a7e6e0e0b9270bd607dd42245763d900f2 100644 (file)
@@ -82,6 +82,12 @@ fi
 AC_SUBST([GNUTLS_LIBS])
 AM_CONDITIONAL([HAVE_GNUTLS], [ ! test "x$GNUTLS_LIBS" = x ])
 
+AC_CHECK_LIB([pam], [pam_start], 
+            [PAM_LIBS='-lpam'
+             AC_DEFINE(HAVE_PAM, 1, [PAM available])])
+AC_SUBST([PAM_LIBS])
+AM_CONDITIONAL([HAVE_PAM], [ ! test "x$PAM_LIBS" = x ])
+
 VNCCONFIG_DIR='vncconfig'
 AC_ARG_ENABLE([vncconfig],
        AS_HELP_STRING([--enable-vncconfig],