File U_add_allowoverride_parameter.patch of Package tigervnc.openSUSE_Leap_42.2_Update

Git-commit: ef0dd758a3fad048c1f04e144b03a3e69b001f21
Patch-Mainline: To be upstreamed
Author: Michal Srb <michalsrb@gmail.com>
Subject: Add AllowOverride parameter.
References: fate#319319

Allows to specify which configuration parameters can be modified on runtime.

diff --git a/unix/xserver/hw/vnc/vncExt.c b/unix/xserver/hw/vnc/vncExt.c
index 43794da..b27115f 100644
--- a/unix/xserver/hw/vnc/vncExt.c
+++ b/unix/xserver/hw/vnc/vncExt.c
@@ -182,17 +182,16 @@ static int ProcVncExtSetParam(ClientPtr client)
   rep.sequenceNumber = client->sequence;
 
   /*
-   * Allow to change only certain parameters.
-   * Changing other parameters (for example PAM service name)
-   * could have negative security impact.
+   * Prevent change of clipboard related parameters if clipboard is disabled.
    */
-  if (strncasecmp(param, "desktop", 7) != 0 &&
-      strncasecmp(param, "AcceptPointerEvents", 19) != 0 &&
-      (vncNoClipboard || strncasecmp(param, "SendCutText", 11) != 0) &&
-      (vncNoClipboard || strncasecmp(param, "AcceptCutText", 13) != 0))
+  if (vncNoClipboard &&
+      (strncasecmp(param, "SendCutText", 11) == 0 ||
+       strncasecmp(param, "AcceptCutText", 13) == 0))
+    goto deny;
+
+  if (!vncOverrideParam(param))
     goto deny;
 
-  vncSetParamSimple(param);
   rep.success = 1;
 
   // Send DesktopName update if desktop name has been changed
diff --git a/unix/xserver/hw/vnc/vncExtInit.cc b/unix/xserver/hw/vnc/vncExtInit.cc
index 863cd36..1d37493 100644
--- a/unix/xserver/hw/vnc/vncExtInit.cc
+++ b/unix/xserver/hw/vnc/vncExtInit.cc
@@ -20,6 +20,9 @@
 #include <stdio.h>
 #include <errno.h>
 
+#include <set>
+#include <string>
+
 #include <rfb/Configuration.h>
 #include <rfb/Logger_stdio.h>
 #include <rfb/LogWriter.h>
@@ -52,6 +55,15 @@ int vncFbstride[MAXSCREENS];
 
 int vncInetdSock = -1;
 
+struct CaseInsensitiveCompare {
+  bool operator() (const std::string &a, const std::string &b) const {
+    return strcasecmp(a.c_str(), b.c_str()) < 0;
+  }
+};
+
+typedef std::set<std::string, CaseInsensitiveCompare> ParamSet;
+static ParamSet allowOverrideSet;
+
 rfb::StringParameter httpDir("httpd",
                              "Directory containing files to serve via HTTP",
                              "");
@@ -69,6 +81,9 @@ rfb::StringParameter interface("interface",
 rfb::BoolParameter avoidShiftNumLock("AvoidShiftNumLock",
                                      "Avoid fake Shift presses for keys affected by NumLock.",
                                      true);
+rfb::StringParameter allowOverride("AllowOverride",
+                                   "Comma separated list of parameters that can be modified using VNC extension.",
+                                   "desktop,AcceptPointerEvents,SendCutText,AcceptCutText");
 
 static PixelFormat vncGetPixelFormat(int scrIdx)
 {
@@ -99,6 +114,19 @@ static PixelFormat vncGetPixelFormat(int scrIdx)
                      redShift, greenShift, blueShift);
 }
 
+static void parseOverrideList(const char *text, ParamSet &out)
+{
+  for (const char* iter = text; ; ++iter) {
+    if (*iter == ',' || *iter == '\0') {
+      out.insert(std::string(text, iter));
+      text = iter + 1;
+
+      if (*iter == '\0')
+        break;
+    }
+  }
+}
+
 void vncExtensionInit(void)
 {
   int ret;
@@ -128,6 +156,10 @@ void vncExtensionInit(void)
   try {
     if (!initialised) {
       rfb::initStdIOLoggers();
+
+      parseOverrideList(allowOverride, allowOverrideSet);
+      allowOverride.setImmutable();
+
       initialised = true;
     }
 
@@ -379,3 +411,16 @@ void vncRefreshScreenLayout(int scrIdx)
 {
   desktop[scrIdx]->refreshScreenLayout();
 }
+
+int vncOverrideParam(const char *nameAndValue)
+{
+  const char* equalSign = strchr(nameAndValue, '=');
+  if (!equalSign)
+    return 0;
+
+  std::string key(nameAndValue, equalSign);
+  if (allowOverrideSet.find(key) == allowOverrideSet.end())
+    return 0;
+
+  return rfb::Configuration::setParam(nameAndValue);
+}
diff --git a/unix/xserver/hw/vnc/vncExtInit.h b/unix/xserver/hw/vnc/vncExtInit.h
index 6430ac0..be6487c 100644
--- a/unix/xserver/hw/vnc/vncExtInit.h
+++ b/unix/xserver/hw/vnc/vncExtInit.h
@@ -90,6 +90,8 @@ void vncPreScreenResize(int scrIdx);
 void vncPostScreenResize(int scrIdx, int success, int width, int height);
 void vncRefreshScreenLayout(int scrIdx);
 
+int vncOverrideParam(const char *nameAndValue);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/unix/xserver/hw/vnc/Xvnc.man b/unix/xserver/hw/vnc/Xvnc.man
index 4a83315..a4d9f8d 100644
--- a/unix/xserver/hw/vnc/Xvnc.man
+++ b/unix/xserver/hw/vnc/Xvnc.man
@@ -300,6 +300,21 @@ Key affected by NumLock often require a fake Shift to be inserted in order
 for the correct symbol to be generated. Turning on this option avoids these
 extra fake Shift events but may result in a slightly different symbol
 (e.g. a Return instead of a keypad Enter).
+.
+.TP
+.B \-AllowOverride
+Comma separated list of parameters that can be modified using VNC extension.
+Parameters can be modified for example using \fBvncconfig\fP(1) program from
+inside a running session.
+
+Allowing override of parameters such as \fBPAMService\fP or \fBPasswordFile\fP
+can negatively impact security if Xvnc runs under different user than the
+programs allowed to override the parameters.
+
+When \fBNoClipboard\fP parameter is set, allowing override of \fBSendCutText\fP
+and \fBAcceptCutText\fP has no effect.
+
+Default is \fBdesktop,AcceptPointerEvents,SendCutText,AcceptCutText\fP.
 
 .SH USAGE WITH INETD
 By configuring the \fBinetd\fP(1) service appropriately, Xvnc can be launched
openSUSE Build Service is sponsored by