Signed-off-by: Martin Koegler <mkoeg...@auto.tuwien.ac.at> --- Windows password validator is contained in the VeNCrypt sources.
common/rfb/Makefile.am | 5 ++ common/rfb/Security.cxx | 21 +++++++ common/rfb/Security.h | 3 + common/rfb/UnixPasswordValidator.cxx | 42 ++++++++++++++ common/rfb/UnixPasswordValidator.h | 35 ++++++++++++ common/rfb/pam.cxx | 99 ++++++++++++++++++++++++++++++++++ configure.ac | 6 ++ 7 files changed, 211 insertions(+), 0 deletions(-) create mode 100644 common/rfb/UnixPasswordValidator.cxx create mode 100644 common/rfb/UnixPasswordValidator.h create mode 100644 common/rfb/pam.cxx diff --git a/common/rfb/Makefile.am b/common/rfb/Makefile.am index 4e5bbd7..86a24e3 100644 --- a/common/rfb/Makefile.am +++ b/common/rfb/Makefile.am @@ -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.cxx +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 diff --git a/common/rfb/Security.cxx b/common/rfb/Security.cxx index 708c10a..3e81961 100644 --- a/common/rfb/Security.cxx +++ b/common/rfb/Security.cxx @@ -33,16 +33,21 @@ #include <rfb/CSecurityVncAuth.h> #include <rfb/CSecurityPlain.h> #include <rdr/Exception.h> +#include <rfb/Exception.h> #include <rfb/LogWriter.h> #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 #include <rfb/CSecurityTLS.h> #include <rfb/SSecurityTLS.h> #endif +#ifdef HAVE_PAM +#include <rfb/UnixPasswordValidator.h> +#endif #include <rfb/util.h> using namespace rdr; @@ -77,6 +82,10 @@ Security::Security(SecurityClassType secClassType) { char *secTypesStr; + valid = NULL; +#ifdef HAVE_PAM + valid = new UnixPasswordValidator(); +#endif switch (secClassType) { case SecurityViewer: secTypesStr = secTypesViewer.getData(); @@ -146,15 +155,27 @@ SSecurity* Security::GetSSecurity(U32 secType) case secTypeNone: return new SSecurityNone(); case secTypeVncAuth: return new SSecurityVncAuth(); case secTypeVeNCrypt: return new SSecurityVeNCrypt(this); + case secTypePlain: + if (!valid) + throw AuthFailureException("No password validator configured"); + return new SSecurityPlain(valid); #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: + if (!valid) + throw AuthFailureException("No password validator configured"); + return new SSecurityStack(secTypeTLSPlain, new SSecurityTLS(true), new SSecurityPlain(valid)); case secTypeX509None: return new SSecurityStack(secTypeX509None, new SSecurityTLS(false)); case secTypeX509Vnc: return new SSecurityStack(secTypeX509None, new SSecurityTLS(false), new SSecurityVncAuth()); + case secTypeX509Plain: + if (!valid) + throw AuthFailureException("No password validator configured"); + return new SSecurityStack(secTypeX509Plain, new SSecurityTLS(true), new SSecurityPlain(valid)); #endif } diff --git a/common/rfb/Security.h b/common/rfb/Security.h index 6ee6b61..1f3cad2 100644 --- a/common/rfb/Security.h +++ b/common/rfb/Security.h @@ -62,6 +62,8 @@ namespace rfb { enum SecurityClassType { SecurityViewer, SecurityServer }; + class PasswordValidator; + class Security { public: /* @@ -105,6 +107,7 @@ namespace rfb { */ private: std::list<rdr::U32> enabledSecTypes; + PasswordValidator *valid; }; const char* secTypeName(rdr::U32 num); diff --git a/common/rfb/UnixPasswordValidator.cxx b/common/rfb/UnixPasswordValidator.cxx new file mode 100644 index 0000000..cc72c8a --- /dev/null +++ b/common/rfb/UnixPasswordValidator.cxx @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2006 Martin Koegler + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include <rfb/Configuration.h> +#include <rfb/Exception.h> +#include <rfb/UnixPasswordValidator.h> + +using namespace rfb; + +static StringParameter pam_service + ("pam_service", "service name for pam password validation", "vnc"); + +int do_pam_auth (const char *service, const char *username, + const char *password); + +bool + UnixPasswordValidator::validateInternal (SConnection * sc, + const char *username, + const char *password) +{ + CharArray service (strDup (pam_service.getData ())); + int ret = do_pam_auth (service.buf, username, password); + if (ret == -1) + throw AuthFailureException ("PAM not supported"); + return ret; +} diff --git a/common/rfb/UnixPasswordValidator.h b/common/rfb/UnixPasswordValidator.h new file mode 100644 index 0000000..fd9b7e2 --- /dev/null +++ b/common/rfb/UnixPasswordValidator.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2006 Martin Koegler + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef PASSWORD_VALIDATOR_H +#define PASSWORD_VALIDATOR_H + +#include <rfb/SSecurityPlain.h> + +namespace rfb +{ + class UnixPasswordValidator:public PasswordValidator + { + protected: + bool validateInternal (SConnection * sc, const char *username, + const char *password); + }; +} + +#endif diff --git a/common/rfb/pam.cxx b/common/rfb/pam.cxx new file mode 100644 index 0000000..dd48167 --- /dev/null +++ b/common/rfb/pam.cxx @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2006 Martin Koegler + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdlib.h> +#include <string.h> +#ifdef HAVE_PAM +#include <security/pam_appl.h> + +typedef struct +{ + const char *username; + const char *password; +} AuthData; + +static int +pam_callback (int count, + const struct pam_message **in, + struct pam_response **out, void *ptr) +{ + int i; + AuthData *auth = (AuthData *) ptr; + struct pam_response *resp = + (struct pam_response *) malloc (sizeof (struct pam_response) * count); + + if (!resp && count) + return PAM_CONV_ERR; + + for (i = 0; i < count; i++) + { + resp[i].resp_retcode = PAM_SUCCESS; + switch (in[i]->msg_style) + { + case PAM_TEXT_INFO: + case PAM_ERROR_MSG: + resp[i].resp = 0; + break; + case PAM_PROMPT_ECHO_ON: /* Send Username */ + resp[i].resp = strdup (auth->username); + break; + case PAM_PROMPT_ECHO_OFF: /* Send Password */ + resp[i].resp = strdup (auth->password); + break; + default: + free (resp); + return PAM_CONV_ERR; + } + } + *out = resp; + return PAM_SUCCESS; +} + + +int +do_pam_auth (const char *service, const char *username, const char *password) +{ + int ret; + AuthData auth = { username, password }; + struct pam_conv conv = { + pam_callback, + &auth + }; + pam_handle_t *h = 0; + ret = pam_start (service, username, &conv, &h); + if (ret == PAM_SUCCESS) + ret = pam_authenticate (h, 0); + if (ret == PAM_SUCCESS) + ret = pam_acct_mgmt (h, 0); + pam_end (h, ret); + return ret == PAM_SUCCESS ? 1 : 0; +} + +#else +int +do_pam_auth (const char *service, const char *username, const char *password) +{ + return -1; +} + +#endif diff --git a/configure.ac b/configure.ac index f6dfc10..8383167 100644 --- a/configure.ac +++ b/configure.ac @@ -84,6 +84,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], -- 1.5.6.5 ------------------------------------------------------------------------------ This SF.net Dev2Dev email is sponsored by: Show off your parallel programming skills. Enter the Intel(R) Threading Challenge 2010. http://p.sf.net/sfu/intel-thread-sfd _______________________________________________ Tigervnc-devel mailing list Tigervnc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/tigervnc-devel