[X2Go-Commits] [nx-libs] 353/429: nxagent: add option -textclipboard

git-admin at x2go.org git-admin at x2go.org
Mon Oct 18 09:37:05 CEST 2021


This is an automated email from the git hooks/post-receive script.

x2go pushed a commit to branch 3.6.x
in repository nx-libs.

commit 90947c1f7c5b345447a8b991e513a60c4f70fbdd
Author: Ulrich Sibiller <uli42 at gmx.de>
Date:   Mon Oct 26 23:52:30 2020 +0100

    nxagent: add option -textclipboard
    
    textclipboard=<bool> in the options file
---
 nx-X11/programs/Xserver/hw/nxagent/Args.c        |  19 ++
 nx-X11/programs/Xserver/hw/nxagent/Clipboard.c   | 228 ++++++++++++++++++++++-
 nx-X11/programs/Xserver/hw/nxagent/Options.c     |   1 +
 nx-X11/programs/Xserver/hw/nxagent/Options.h     |   7 +
 nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1 |  13 ++
 5 files changed, 261 insertions(+), 7 deletions(-)

diff --git a/nx-X11/programs/Xserver/hw/nxagent/Args.c b/nx-X11/programs/Xserver/hw/nxagent/Args.c
index be13efacd..ea17e4813 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Args.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Args.c
@@ -972,6 +972,12 @@ int ddxProcessArgument(int argc, char *argv[], int i)
     return 2;
   }
 
+  if (!strcmp(argv[i], "-textclipboard"))
+  {
+    nxagentChangeOption(TextClipboard, True);
+    return 1;
+  }
+
   if (!strcmp(argv[i], "-bs"))
   {
     nxagentChangeOption(BackingStore, BackingStoreNever);
@@ -1487,6 +1493,18 @@ static void nxagentParseSingleOption(char *name, char *value)
     }
     return;
   }
+  else if (!strcmp(name, "textclipboard"))
+  {
+    if (!strcmp(value, "0"))
+    {
+      nxagentChangeOption(TextClipboard, False);
+    }
+    else
+    {
+      nxagentChangeOption(TextClipboard, True);
+    }
+    return;
+  }
   else
   {
     #ifdef DEBUG
@@ -2129,6 +2147,7 @@ void ddxUseMsg(void)
   ErrorF("-nokbreset             don't reset keyboard device if the session is resumed\n");
   ErrorF("-noxkblock             always allow applications to change layout through XKEYBOARD\n");
   ErrorF("-autograb              enable autograb\n");
+  ErrorF("-textclipboard         limit clipboard data to text only\n");
   ErrorF("-irlimit               maximum image data rate to the encoder input in kB/s.\n");
   ErrorF("-tile WxH              maximum size of image tiles (minimum allowed: 32x32)\n");
   ErrorF("-keystrokefile file    file with keyboard shortcut definitions\n");
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
index 28d56b758..fb2595e68 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
@@ -264,6 +264,7 @@ XFixesAgentInfoRec nxagentXFixesInfo = { -1, -1, -1, False };
 
 extern Display *nxagentDisplay;
 
+static Bool isTextTarget(XlibAtom target);
 static void setClientSelectionStage(int stage, int index);
 static void endTransfer(Bool success, int index);
 #define SELECTION_SUCCESS True
@@ -562,6 +563,48 @@ static void sendSelectionNotifyEventToClient(ClientPtr client,
   sendEventToClient(client, &x);
 }
 
+/*
+ * Check if target is a valid text content type target sent by the real X
+ * server, like .e.g XA_STRING or UTF8_STRING.
+ */
+static Bool isTextTarget(XlibAtom target)
+{
+  if (target == XA_STRING)
+  {
+    #ifdef DEBUG
+    fprintf(stderr, "%s: valid target [XA_STRING].\n", __func__);
+    #endif
+    return True;
+  }
+  else if (target == serverTEXT)
+  {
+    #ifdef DEBUG
+    fprintf(stderr, "%s: valid target [TEXT].\n", __func__);
+    #endif
+    return True;
+  }
+  else if (target == serverUTF8_STRING)
+  {
+    #ifdef DEBUG
+    fprintf(stderr, "%s: valid target [UTF8_STRING].\n", __func__);
+    #endif
+    return True;
+  }
+  else if (target == serverCOMPOUND_TEXT)
+  {
+    #ifdef DEBUG
+    fprintf(stderr, "%s: valid target [COMPOUND_TEXT].\n", __func__);
+    #endif
+    return True;
+  }
+  /* FIXME: add text/plain */
+
+  #ifdef DEBUG
+  fprintf(stderr, "%s: not a text target [%lu].\n", __func__, target);
+  #endif
+  return False;
+}
+
 static void initSelectionOwnerData(int index)
 {
   lastSelectionOwner[index].client = NullClient;
@@ -806,7 +849,61 @@ void nxagentHandleSelectionRequestFromXServer(XEvent *X)
     return;
   }
 
-  if (X->xselectionrequest.target == serverTIMESTAMP)
+  if (X->xselectionrequest.target == serverTARGETS)
+  {
+    /*
+     * In TextClipboard mode answer with a predefined list of
+     * targets. This is just the previous implementation of handling
+     * the clipboard.
+     */
+    if (nxagentOption(TextClipboard))
+    {
+      /*
+       * the selection request target is TARGETS. The requestor is
+       * asking for a list of supported data formats.
+       *
+       * The selection does not matter here, we will return this for
+       * PRIMARY and CLIPBOARD.
+       *
+       * The list is aligned with the one in nxagentConvertSelection()
+       * and in isTextTarget().
+       */
+
+      XlibAtom targets[] = {XA_STRING, serverUTF8_STRING, serverTEXT, serverCOMPOUND_TEXT,
+                            serverTARGETS, serverTIMESTAMP};
+      int numTargets = sizeof(targets) / sizeof(targets[0]);
+
+      #ifdef DEBUG
+      fprintf(stderr, "%s: Sending %d available targets:\n", __func__, numTargets);
+      for (int i = 0; i < numTargets; i++)
+      {
+        fprintf(stderr, "%s: %ld %s\n", __func__, targets[i], NameForRemAtom(targets[i]));
+      }
+      fprintf(stderr, "\n");
+      #endif
+
+      /*
+       * pass on the requested list by setting the property provided
+       * by the requestor accordingly.
+       */
+      XChangeProperty(nxagentDisplay,
+                      X->xselectionrequest.requestor,
+                      X->xselectionrequest.property,
+                      XInternAtom(nxagentDisplay, "ATOM", 0),
+                      32,
+                      PropModeReplace,
+                      (unsigned char*)targets,
+                      numTargets);
+
+      replyRequestSelectionToXServer(X, True);
+      return;
+    }
+    else
+    {
+      /* do nothing, let TARGETS be passed on to the owner later */
+    }
+  }
+  else if (X->xselectionrequest.target == serverTIMESTAMP)
   {
     /*
      * Section 2.6.2 of the ICCCM states:
@@ -882,12 +979,28 @@ void nxagentHandleSelectionRequestFromXServer(XEvent *X)
     replyRequestSelectionToXServer(X, False);
     return;
   }
-  else
+
+  if (nxagentOption(TextClipboard))
   {
-    fprintf(stderr, "%s: target [%ld][%s].\n", __func__, X->xselectionrequest.target,
-                NameForRemAtom(X->xselectionrequest.target));
+    if (!isTextTarget(X->xselectionrequest.target))
+    {
+      #ifdef DEBUG
+      fprintf(stderr, "%s: denying request for non-text target [%ld][%s].\n", __func__,
+                  X->xselectionrequest.target, NameForRemAtom(X->xselectionrequest.target));
+      #endif
+
+      replyRequestSelectionToXServer(X, False);
+
+      return;
+    }
+    /* go on, target is acceptable */
   }
 
+  #ifdef DEBUG
+  fprintf(stderr, "%s: target [%ld][%s].\n", __func__, X->xselectionrequest.target,
+              NameForRemAtom(X->xselectionrequest.target));
+  #endif
+
   /*
    * reaching this means the request is a normal, valid request. We
    * can process it now.
@@ -967,12 +1080,34 @@ void nxagentHandleSelectionRequestFromXServer(XEvent *X)
       /*
        * Don't send the same window, some programs are clever and
        * verify cut and paste operations inside the same window and
-       * don't Notify at all.
+       * don't notify at all.
        *
        * x.u.selectionRequest.requestor = lastSelectionOwner[index].window;
        */
 
-      x.u.selectionRequest.target = nxagentRemoteToLocalAtom(X->xselectionrequest.target);
+      /*
+       * if textclipboard is requested simply use the previous clipboard
+       * handling code
+       */
+      if (nxagentOption(TextClipboard))
+      {
+        /* by dimbor */
+        if (X->xselectionrequest.target != XA_STRING)
+        {
+          lastServers[index].target = serverUTF8_STRING;
+          /* by dimbor (idea from zahvatov) */
+          x.u.selectionRequest.target = clientUTF8_STRING;
+        }
+        else
+        {
+          x.u.selectionRequest.target = XA_STRING;
+        }
+      }
+      else
+      {
+	x.u.selectionRequest.target = nxagentRemoteToLocalAtom(X->xselectionrequest.target);
+      }
+
       sendEventToClient(lastSelectionOwner[index].client, &x);
 
       #ifdef DEBUG
@@ -2008,6 +2143,64 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection,
     }
   }
 
+  /*
+   * The selection request target is TARGETS. The requestor is asking
+   * for a list of supported data formats.
+   */
+
+  if (target == clientTARGETS)
+  {
+    /*
+     * In TextClipboard mode answer with a predefined list that was used
+     * in in previous versions.
+     */
+    if (nxagentOption(TextClipboard))
+    {
+      /*
+       * The list is aligned with the one in
+       * nxagentHandleSelectionRequestFromXServer.
+       */
+      Atom targets[] = {XA_STRING,
+                        clientUTF8_STRING,
+#if 0
+                        clientTEXT,
+                        clientCOMPOUND_TEXT,
+#endif
+                        clientTARGETS,
+                        clientTIMESTAMP};
+      int numTargets = sizeof(targets) / sizeof(targets[0]);
+
+      #ifdef DEBUG
+      fprintf(stderr, "%s: Sending %d available targets:\n", __func__, numTargets);
+      for (int i = 0; i < numTargets; i++)
+      {
+        fprintf(stderr, "%s: %d %s\n", __func__, targets[i], NameForIntAtom(targets[i]));
+      }
+      #endif
+
+      ChangeWindowProperty(pWin,
+                           property,
+                           MakeAtom("ATOM", 4, 1),
+                           sizeof(Atom)*8,
+                           PropModeReplace,
+                           numTargets,
+                           targets,
+                           1);
+
+      sendSelectionNotifyEventToClient(client, time, requestor, selection,
+                                           target, property);
+
+      return 1;
+    }
+    else
+    {
+      /*
+       * do nothing - TARGETS will be handled like any other target
+       * and passed on to the owner on the remote side.
+       */
+    }
+  }
+
   /*
    * Section 2.6.2 of the ICCCM states:
    * "TIMESTAMP - To avoid some race conditions, it is important
@@ -2018,7 +2211,7 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection,
    * support conversion to TIMESTAMP, returning the timestamp they
    * used to obtain the selection."
    */
-  if (target == clientTIMESTAMP)
+  else if (target == clientTIMESTAMP)
   {
     /*
      * "If the specified property is not None, the owner should place
@@ -2087,6 +2280,27 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection,
     return 1;
   }
 
+  /* in TextClipboard mode reject all non-text targets */
+  if (nxagentOption(TextClipboard))
+  {
+    if (!isTextTarget(translateLocalToRemoteTarget(target)))
+    {
+      #ifdef DEBUG
+      fprintf(stderr, "%s: denying request for non-text target [%d][%s].\n", __func__,
+                  target, NameForIntAtom(target));
+      #endif
+
+      sendSelectionNotifyEventToClient(client, time, requestor, selection, target, None);
+      return 1;
+    }
+    /* go on, target is acceptable */
+  }
+
+  #ifdef DEBUG
+  fprintf(stderr, "%s: target [%d][%s].\n", __func__, target,
+              NameForIntAtom(target));
+  #endif
+
   if (lastClients[index].clientPtr == client)
   {
     if (GetTimeInMillis() - lastClients[index].reqTime < ACCUM_TIME)
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Options.c b/nx-X11/programs/Xserver/hw/nxagent/Options.c
index be6e5d5e1..8e6249e4c 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Options.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Options.c
@@ -88,6 +88,7 @@ void nxagentInitOptions(void)
   nxagentOptions.BackingStore = BackingStoreUndefined;
 
   nxagentOptions.Clipboard = ClipboardBoth;
+  nxagentOptions.TextClipboard = False;
 
   nxagentOptions.SharedMemory = True;
 
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Options.h b/nx-X11/programs/Xserver/hw/nxagent/Options.h
index a99f4aee2..d3c8c7150 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Options.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Options.h
@@ -194,6 +194,13 @@ typedef struct _AgentOptions
    */
   ClipboardMode Clipboard;
 
+  /*
+   * transfer TARGETS to remote side or answer with a limited
+   * hardcoded text target list
+   * Should be Bool but we'd have to include Xlib.h for that
+   */
+  int TextClipboard;
+
   /*
    * Enable agent to use the MITSHM extension in path from remote
    * proxy to the real X server.
diff --git a/nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1 b/nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1
index 74349cda7..f373cb239 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1
+++ b/nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1
@@ -465,6 +465,10 @@ The session id.
 .B \-autograb
 enable autograb mode on \fBnxagent\fR startup. The autograb feature can be toggled via nxagent keystrokes
 .TP 8
+.B \-textclipboard
+force text-only clipboard \fBnxagent\fR startup. See option file
+option \fBtextclipboard=<bool>\fR for an explanation.
+.TP 8
 .B \-nxrealwindowprop
 set property NX_REAL_WINDOW for each X11 client inside \fBnxagent\fR,
 providing the window XID of the corresponding window object on the X
@@ -721,6 +725,15 @@ Limit clipboard data exchange to work only in one direction: from nxagent to rea
 Disable any clipboard data exchange. Clipboard will still work inside the nxagent and on the real X server, but no data exchange will be possible.
 .RE
 .TP 8
+.B textclipboard=<bool>
+enable (set to \fI1\fR) or disable (set to \fI0\fR) text-only
+clipboard. Text-only clipboard is the old (<= 3.5.99.26) clipboard
+behaviour where you could only copy and paste text strings (no
+graphics, no rich text, ...). Using this mode been seen as a security feature
+as it effectively prevents transferring dangerous binary data,
+e.g. manipulated graphics by accident. On the other hand it's also
+less comfortable.  (default: disabled)
+.TP 8
 .B streaming=<bool>
 enable (set to \fI1\fR) or disable (set to \fI0\fR) streaming support for images, not fully implemented yet and thus non-functional. (default: disabled)
 .TP 8

--
Alioth's /home/x2go-admin/maintenancescripts/git/hooks/post-receive-email on /srv/git/code.x2go.org/nx-libs.git


More information about the x2go-commits mailing list