Description: Cache the VNC PasswordFile.
 In case the home directory becomes inaccessible, e.g., due to an expired
 Kerberos ticket, the VNC server still needs the content of the VNC password
 file. Otherwise, it is no longer possible to log in using the security types
 VncAuth or X509Vnc.
Author: Joachim Falk <joachim.falk@gmx.de>
Forwarded: no

Index: pkg-tigervnc/common/rfb/SSecurityVncAuth.cxx
===================================================================
--- pkg-tigervnc.orig/common/rfb/SSecurityVncAuth.cxx
+++ pkg-tigervnc/common/rfb/SSecurityVncAuth.cxx
@@ -44,7 +44,7 @@ using namespace rfb;
 
 static LogWriter vlog("SVncAuth");
 
-StringParameter SSecurityVncAuth::vncAuthPasswdFile
+VncAuthPasswdFile SSecurityVncAuth::vncAuthPasswdFile
 ("PasswordFile", "Password file for VNC authentication", "");
 AliasParameter rfbauth("rfbauth", "Alias for PasswordFile",
 		       &SSecurityVncAuth::vncAuthPasswdFile);
@@ -116,9 +116,51 @@ bool SSecurityVncAuth::processMsg()
   throw auth_error("Authentication failed");
 }
 
+VncAuthPasswdFile::VncAuthPasswdFile(const char* name_, const char* desc_, const char* v)
+: StringParameter(name_, desc_, v)
+{
+}
+
+bool VncAuthPasswdFile::setParam(const char* value) {
+  bool status = this->StringParameter::setParam(value);
+  if (status && !getValueStr().empty())
+    readPasswdFile();
+  return status;
+}
+
+bool VncAuthPasswdFile::getPasswd(
+    std::vector<uint8_t> &obfuscated
+  , std::vector<uint8_t> &obfuscatedReadOnly)
+{
+  if (!getValueStr().empty() && (readPasswdFile() || this->obfuscated.size() > 0)) {
+    obfuscated = this->obfuscated;
+    obfuscatedReadOnly = this->obfuscatedReadOnly;
+    return true;
+  } else
+    return false;
+}
+
+bool VncAuthPasswdFile::readPasswdFile() {
+  const char *fname = *this;
+
+  FILE* fp = fopen(fname, "r");
+  if (!fp) {
+    vlog.error("Opening password file '%s' failed", fname);
+    return false;
+  }
+
+  vlog.debug("Reading password file");
+  obfuscated.resize(8);
+  obfuscated.resize(fread(obfuscated.data(), 1, 8, fp));
+  obfuscatedReadOnly.resize(8);
+  obfuscatedReadOnly.resize(fread(obfuscatedReadOnly.data(), 1, 8, fp));
+  fclose(fp);
+  return true;
+}
+
 VncAuthPasswdParameter::VncAuthPasswdParameter(const char* name_,
                                                const char* desc,
-                                               StringParameter* passwdFile_)
+                                               VncAuthPasswdFile* passwdFile_)
 : BinaryParameter(name_, desc, nullptr, 0),
   passwdFile(passwdFile_)
 {
@@ -130,24 +172,10 @@ void VncAuthPasswdParameter::getVncAuthP
 
   if (obfuscated.size() == 0) {
     if (passwdFile) {
-      const char *fname = *passwdFile;
-      if (!fname[0]) {
+      if (!passwdFile->getPasswd(obfuscated, obfuscatedReadOnly)) {
         vlog.info("Neither %s nor %s params set", getName(), passwdFile->getName());
         return;
       }
-
-      FILE* fp = fopen(fname, "r");
-      if (!fp) {
-        vlog.error("Opening password file '%s' failed", fname);
-        return;
-      }
-
-      vlog.debug("Reading password file");
-      obfuscated.resize(8);
-      obfuscated.resize(fread(obfuscated.data(), 1, 8, fp));
-      obfuscatedReadOnly.resize(8);
-      obfuscatedReadOnly.resize(fread(obfuscatedReadOnly.data(), 1, 8, fp));
-      fclose(fp);
     } else {
       vlog.info("%s parameter not set", getName());
     }
Index: pkg-tigervnc/common/rfb/SSecurityVncAuth.h
===================================================================
--- pkg-tigervnc.orig/common/rfb/SSecurityVncAuth.h
+++ pkg-tigervnc/common/rfb/SSecurityVncAuth.h
@@ -32,6 +32,20 @@
 
 namespace rfb {
 
+  class VncAuthPasswdFile : public StringParameter {
+  public:
+    VncAuthPasswdFile(const char* name_, const char* desc_, const char* v);
+
+    bool setParam(const char* value) override;
+
+    bool getPasswd(std::vector<uint8_t> &obfuscated, std::vector<uint8_t> &obfuscatedReadOnly);
+
+  private:
+    std::vector<uint8_t> obfuscated, obfuscatedReadOnly;
+
+    bool readPasswdFile();
+  };
+
   class VncAuthPasswdGetter {
   public:
     // getVncAuthPasswd() fills buffer of given password and readOnlyPassword.
@@ -43,10 +57,10 @@ namespace rfb {
 
   class VncAuthPasswdParameter : public VncAuthPasswdGetter, BinaryParameter {
   public:
-    VncAuthPasswdParameter(const char* name, const char* desc, StringParameter* passwdFile_);
+    VncAuthPasswdParameter(const char* name, const char* desc, VncAuthPasswdFile* passwdFile_);
     void getVncAuthPasswd(std::string *password, std::string *readOnlyPassword) override;
   protected:
-    StringParameter* passwdFile;
+    VncAuthPasswdFile* passwdFile;
   };
 
   class SSecurityVncAuth : public SSecurity {
@@ -56,7 +70,7 @@ namespace rfb {
     int getType() const override {return secTypeVncAuth;}
     const char* getUserName() const override {return nullptr;}
     AccessRights getAccessRights() const override { return accessRights; }
-    static StringParameter vncAuthPasswdFile;
+    static VncAuthPasswdFile vncAuthPasswdFile;
     static VncAuthPasswdParameter vncAuthPasswd;
   private:
     bool verifyResponse(const char* password);
