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
#include <rfb/SConnection.h>
#include <rfb/Exception.h>
#include <rdr/InStream.h>
+#ifdef HAVE_PAM
+#include <rfb/UnixPasswordValidator.h>
+#endif
using namespace rfb;
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)
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;
}
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;
};
#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
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
}
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],