Eamon,<br><br>Thanks for the selection patch, I will review it next week and <br>send my comments directly to you.<br><br>I have implemented a much less clean version (hack) of selection <br>redirection for a trusted X server that I am working on, and have
<br>not had trouble with clients rejecting synthetic requests -- but <br>I have not done much testing with modern X clients so I may be <br>blissfully ignorant of problems.<br><br>One problem, outside the scope of your patch, that I have had
<br>with redirecting selections is caused by the hardcoded default <br>Xt selection timeout. If the selection manager causes the selection<br>reply to be delayed by more that 5000 milliseconds the Xt toolkit <br>will ignore the selection.
<br><br>This is the code from lib/Xt/Seletion.c that causes the trouble:<br><br> void _XtSetDefaultSelectionTimeout(<br> unsigned long *timeout)<br> {<br> *timeout = 5000; /* default to 5 seconds */<br> }
<br><br>I do not have a good solution for the timeout. My workaround<br>was to add a similar timeout to the selection manager so it<br>can let the user know that the selection might be ignored.<br><br>Pat Kane<br>--------
<br><br><br><div><span class="gmail_quote">On 3/21/07, <b class="gmail_sendername">Eamon Walsh</b> <<a href="mailto:ewalsh@tycho.nsa.gov">ewalsh@tycho.nsa.gov</a>> wrote:</span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
This patch implements support for dealing with selections in XACE.<br>The requirements are to support the usual access check, and also<br>to support redirecting ConvertSelection requests to another client<br>application.<br>
<br>The patch introduces new fields into the Selection structure, destclient<br>and destwindow, and adds an XACE hook in the selection request procs.<br><br>The destclient field is where the SelectionRequest message actually
<br>gets sent when doing a ConvertSelection. This could be a selection<br>manager application that can send the SelectionRequest on to<br>the real selection owner, actively serve as a middleman, or send a<br>SelectionNotify None back to the requestor to cancel the transfer.
<br><br>The destwindow field is what gets reported as the selection owner from<br>GetSelectionOwner requests. This could be used to further redirect things<br>to the selection manager. I'm aware of the XFixes selection events; the
<br>behavior of those is not changed.<br><br>XACE module authors can register for this hook, use the hook arguments<br>to decide whether to redirect, and change the dest field accordingly.<br>Returning FALSE from the hook is a third option, which ignores the
<br>request (sends None back to requestor).<br><br>This patch is based on the description of how selections work from the<br>ICCCM. There are some details I'm not sure of, such as whether applications<br>will accept a synthetic SelectionRequest as in the example above.
<br><br>Comments?<br><br>--<br> Xext/xace.c | 11 +++++++++++<br> Xext/xace.h | 17 +++++++++--------<br> Xext/xacestr.h | 9 +++++++++<br> dix/dispatch.c | 25 +++++++++++++++++--------<br>
include/selection.h | 4 ++++<br> 5 files changed, 50 insertions(+), 16 deletions(-)<br><br>--<br>diff --git a/Xext/xace.c b/Xext/xace.c<br>index ee0f39c..9502b5d 100644<br>--- a/Xext/xace.c<br>+++ b/Xext/xace.c<br>@@ -147,6 +147,17 @@ int XaceHook(int hook, ...)
<br> prv = &rec.rval;<br> break;<br> }<br>+ case XACE_SELECTION_ACCESS: {<br>+ XaceSelectionAccessRec rec = {<br>+ va_arg(ap, ClientPtr),<br>+ va_arg(ap, Selection*),
<br>+ va_arg(ap, Mask),<br>+ TRUE /* default allow */<br>+ };<br>+ calldata = &rec;<br>+ prv = &rec.rval;<br>+ break;<br>+ }<br> case XACE_SITE_POLICY: {
<br> XaceSitePolicyRec rec = {<br> va_arg(ap, char*),<br>diff --git a/Xext/xace.h b/Xext/xace.h<br>index 7360dae..d3d5a84 100644<br>--- a/Xext/xace.h<br>+++ b/Xext/xace.h<br>@@ -28,7 +28,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
<br> #ifdef XACE<br><br> #define XACE_EXTENSION_NAME "XAccessControlExtension"<br>-#define XACE_MAJOR_VERSION 1<br>+#define XACE_MAJOR_VERSION 2<br> #define XACE_MINOR_VERSION 0
<br><br> #include "pixmap.h" /* for DrawablePtr */<br>@@ -50,13 +50,14 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.<br> #define XACE_BACKGRND_ACCESS 7<br> #define XACE_EXT_ACCESS 8
<br> #define XACE_HOSTLIST_ACCESS 9<br>-#define XACE_SITE_POLICY 10<br>-#define XACE_DECLARE_EXT_SECURE 11<br>-#define XACE_AUTH_AVAIL 12<br>-#define XACE_KEY_AVAIL 13
<br>-#define XACE_AUDIT_BEGIN 14<br>-#define XACE_AUDIT_END 15<br>-#define XACE_NUM_HOOKS 16<br>+#define XACE_SELECTION_ACCESS 10<br>+#define XACE_SITE_POLICY 11
<br>+#define XACE_DECLARE_EXT_SECURE 12<br>+#define XACE_AUTH_AVAIL 13<br>+#define XACE_KEY_AVAIL 14<br>+#define XACE_AUDIT_BEGIN 15<br>+#define XACE_AUDIT_END 16
<br>+#define XACE_NUM_HOOKS 17<br><br> extern CallbackListPtr XaceHooks[XACE_NUM_HOOKS];<br><br>diff --git a/Xext/xacestr.h b/Xext/xacestr.h<br>index bd30883..edf7b66 100644<br>--- a/Xext/xacestr.h<br>+++ b/Xext/xacestr.h
<br>@@ -27,6 +27,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.<br> #include "gcstruct.h"<br> #include "windowstr.h"<br> #include "inputstr.h"<br>+#include "
selection.h"<br> #include "xace.h"<br><br> /* XACE_CORE_DISPATCH */<br>@@ -93,6 +94,14 @@ typedef struct {<br> int rval;<br> } XaceHostlistAccessRec;<br><br>+/* XACE_SELECTION_ACCESS */<br>+typedef struct {
<br>+ ClientPtr client;<br>+ Selection *selection;<br>+ Mask access_mode;<br>+ int rval;<br>+} XaceSelectionAccessRec;<br>+<br> /* XACE_SITE_POLICY */<br> typedef struct {<br> char *policyString;<br>diff --git a/dix/dispatch.c b/dix/dispatch.c
<br>index d44687e..e4bc937 100644<br>--- a/dix/dispatch.c<br>+++ b/dix/dispatch.c<br>@@ -1074,11 +1074,16 @@ ProcSetSelectionOwner(register ClientPtr client)<br> NumCurrentSelections++;<br> CurrentSelections = newsels;
<br> CurrentSelections[i].selection = stuff->selection;<br>+ CurrentSelections[i].devPrivates = NULL;<br> }<br>+ dixFreePrivates(CurrentSelections[i].devPrivates);<br> CurrentSelections[i].lastTimeChanged = time;
<br> CurrentSelections[i].window = stuff->window;<br>+ CurrentSelections[i].destwindow = stuff->window;<br> CurrentSelections[i].pWin = pWin;<br> CurrentSelections[i].client = (pWin ? client : NullClient);
<br>+ CurrentSelections[i].destclient = (pWin ? client : NullClient);<br>+ CurrentSelections[i].devPrivates = NULL;<br> if (SelectionCallback)<br> {<br> SelectionInfoRec info;<br>@@ -1113,8 +1118,10 @@ ProcGetSelectionOwner(register ClientPtr client)
<br> reply.type = X_Reply;<br> reply.length = 0;<br> reply.sequenceNumber = client->sequence;<br>- if (i < NumCurrentSelections)<br>- reply.owner = CurrentSelections[i].window;
<br>+ if (i < NumCurrentSelections &&<br>+ XaceHook(XACE_SELECTION_ACCESS, client, &CurrentSelections[i],<br>+ DixReadAccess))<br>+ reply.owner = CurrentSelections[i].destwindow;
<br> else<br> reply.owner = None;<br> WriteReplyToClient(client, sizeof(xGetSelectionOwnerReply), &reply);<br>@@ -1153,20 +1160,18 @@ ProcConvertSelection(register ClientPtr client)<br> CurrentSelections[i].selection != stuff->selection) i++;
<br> if ((i < NumCurrentSelections) &&<br> (CurrentSelections[i].window != None) &&<br>- XaceHook(XACE_RESOURCE_ACCESS, client,<br>- CurrentSelections[i].window, RT_WINDOW,
<br>- DixReadAccess, CurrentSelections[i].pWin))<br>+ XaceHook(XACE_SELECTION_ACCESS, client, &CurrentSelections[i],<br>+ DixReadAccess))<br> {<br> event.u.u.type
= SelectionRequest;<br> event.u.selectionRequest.time = stuff->time;<br>- event.u.selectionRequest.owner =<br>- CurrentSelections[i].window;<br>+ event.u.selectionRequest.owner
= CurrentSelections[i].window;<br> event.u.selectionRequest.requestor = stuff->requestor;<br> event.u.selectionRequest.selection = stuff->selection;<br> event.u.selectionRequest.target
= stuff->target;<br> event.u.selectionRequest.property = stuff->property;<br> if (TryClientEvents(<br>- CurrentSelections[i].client, &event, 1, NoEventMask,<br>+ CurrentSelections[i].destclient, &event, 1, NoEventMask,
<br> NoEventMask /* CantBeFiltered */, NullGrab))<br> return (client->noClientException);<br> }<br>@@ -4021,9 +4026,11 @@ DeleteWindowFromAnySelections(WindowPtr pWin)<br>
info.kind = SelectionWindowDestroy;<br> CallCallbacks(&SelectionCallback, &info);<br> }<br>+ dixFreePrivates(CurrentSelections[i].devPrivates);<br> CurrentSelections[i].pWin = (WindowPtr)NULL;
<br> CurrentSelections[i].window = None;<br> CurrentSelections[i].client = NullClient;<br>+ CurrentSelections[i].devPrivates = NULL;<br> }<br> }<br><br>@@ -4043,9 +4050,11 @@ DeleteClientFromAnySelections(ClientPtr client)
<br> info.kind = SelectionWindowDestroy;<br> CallCallbacks(&SelectionCallback, &info);<br> }<br>+ dixFreePrivates(CurrentSelections[i].devPrivates);<br> CurrentSelections[i].pWin = (WindowPtr)NULL;
<br> CurrentSelections[i].window = None;<br> CurrentSelections[i].client = NullClient;<br>+ CurrentSelections[i].devPrivates = NULL;<br> }<br> }<br><br>diff --git a/include/selection.h b/include/selection.h
<br>index fbe7cfc..9347376 100644<br>--- a/include/selection.h<br>+++ b/include/selection.h<br>@@ -50,6 +50,7 @@ SOFTWARE.<br> ******************************************************************/<br><br> #include "dixstruct.h
"<br>+#include "privates.h"<br> /*<br> *<br> * Selection data structures<br>@@ -61,6 +62,9 @@ typedef struct _Selection {<br> Window window;<br> WindowPtr pWin;<br> ClientPtr client;<br>+ ClientPtr destclient; /* support for redirection */
<br>+ Window destwindow; /* support for redirection */<br>+ PrivateRec *devPrivates;<br> } Selection;<br><br> #endif /* SELECTION_H */<br><br>_______________________________________________<br>xorg mailing list<br>
<a href="mailto:xorg@lists.freedesktop.org">xorg@lists.freedesktop.org</a><br><a href="http://lists.freedesktop.org/mailman/listinfo/xorg">http://lists.freedesktop.org/mailman/listinfo/xorg</a><br></blockquote></div><br>