On Sun, Jan 12, 2020 at 02:59:46PM +0100, Benjamin Baier wrote:
>
> Here is my status on this.
>
> Claws-mail 3.17.4p2 has the backout diff so all the testing below was done
> with
> claws-mail 3.17.4p1.
>
> Following the advise from Thomas Dickey i compiled libXmu with
> CONFIGURE_ARGS+= --disable-tcp-transport
> which sets #undef TCPCONN
> which is only used once in libXmu/src/CvtStdSel.c where now the offending code
> is disabled. So this option only affects Copy&Paste actions.
Yes that prevents xterm from doing DNS resolution if asked for the IP
address of the selection owner.
>
> Everything fixed, everything still works with this setting.
>
> Copy from | Paste into | Result
> -----------------------------------------------
> local xterm | claws-mail | OK
> local xterm | ssh -XY ... xterm | OK
> ssh -XY ... xterm | claws-mail | OK
> ssh -XY ... xterm | local xterm | OK
>
> So I will be running with the --disable-tcp-transport flag and see if I get
> other misbehaviour, but i suspect not.
Apparently claws-mail, patched to accept image pastes does the
IP_ADDRESS query for nothing (and ignores the result).
>
> Only one other consumer in base, which is xenocara/app/xlockmore.
> The only thing I'm worried about is the 200+ ports that have an libXmu
> dependency declared.
No: it's not the consumers of XmuConvertStandardSelection() that
matter, The question is how other apps requsting the IP address of the
selection owner, and how they behave if this feature is removed from
Xmu it one way or the other.
I guess, given that there there have been no other reports since the
introdution of the xterm(1) pledges that there are no or very few
applications that cares, but at least Gtk has implemented support for
this.
The patch below tries to get an IP adress at startup (before any
pledge()) and caches it. It's also possible to not add the constructor
and always return 127.0.0.1 when queried.
And below the patch it the small test program I wrote to test how
various applications react to the different selection target
requests.
Thoughts, oks ?
Index: src/CvtStdSel.c
===================================================================
RCS file: /cvs/OpenBSD/xenocara/lib/libXmu/src/CvtStdSel.c,v
retrieving revision 1.5
diff -u -p -u -r1.5 CvtStdSel.c
--- src/CvtStdSel.c 28 Sep 2013 17:31:53 -0000 1.5
+++ src/CvtStdSel.c 12 Jan 2020 14:50:09 -0000
@@ -101,6 +101,30 @@ in this Software without prior written a
static char *get_os_name(void);
static Bool isApplicationShell(Widget);
+#ifdef __OpenBSD__
+/* Get host address in constructor to avoid doing it after pledge() */
+static uint32_t addr = htonl(0x7f000002);
+static void __attribute__((constructor)) _XmuInitIpAddress(void);
+
+static void __attribute__((constructor))
+_XmuInitIpAddress(void)
+{
+ char hostname[1024];
+ struct hostent *hostp;
+
+ hostname[0] = '\0';
+ XmuGetHostname (hostname, sizeof hostname);
+
+ if ((hostp = _XGethostbyname (hostname,hparams)) == NULL) {
+ return;
+ }
+ if (hostp->h_addrtype != AF_INET) {
+ return;
+ }
+ memmove(&addr, hostp->h_addr, sizeof(addr));
+}
+#endif
+
/*
* Implementation
*/
@@ -221,6 +245,7 @@ XmuConvertStandardSelection(Widget w, Ti
}
#if defined(TCPCONN)
if (*target == XA_IP_ADDRESS(d)) {
+#ifndef __OpenBSD__
char hostname[1024];
#ifdef XTHREADS_NEEDS_BYNAMEPARAMS
_Xgethostbynameparams hparams;
@@ -240,6 +265,15 @@ XmuConvertStandardSelection(Widget w, Ti
*type = XA_NET_ADDRESS(d);
*format = 8;
return True;
+#else /* __OpenBSD__ */
+ /* return cached value */
+ *length = sizeof(addr);
+ *value = XtMalloc(sizeof(addr));
+ memcpy(*value, &addr, sizeof(addr));
+ *type = XA_NET_ADDRESS(d);
+ *format = 8;
+ return True;
+#endif
}
#endif
if (*target == XA_USER(d)) {
--8<------------------------------------------------------------------
/*
* Copyright (c) 2020 Matthieu Herrb <[email protected]>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* cc -I/usr/X11R6/include -g -Wall tsel.c \
-L/usr/X11R6/lib -lXt -lXmu -lXaw -lX11 -o tsel */
#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>
#include <X11/Xlib.h>
#include <X11/X.h>
#include <X11/Xatom.h>
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Xmu/StdSel.h>
#include <X11/Xmu/Atoms.h>
#include <X11/Xaw/Command.h>
Atom *targets = NULL;
int num_targets = 0;
static void
targets_cb(Widget w, XtPointer client_data, Atom *selection, Atom *type,
XtPointer value, unsigned long *length, int *format)
{
if (*type != XA_ATOM)
return;
targets = reallocarray(NULL, *length, sizeof(Atom));
if (targets == NULL)
return;
num_targets = *length;
printf("Targets:\n");
for (int i = 0; i < num_targets; i++) {
targets[i] = *((Atom *)value + i);
printf("%s\n", XGetAtomName(XtDisplay(w), targets[i]));
}
}
static void
sel_cb(Widget w, XtPointer client_data, Atom *selection, Atom *type,
XtPointer value, unsigned long *length, int *format)
{
Display *dpy = XtDisplay(w);
int i;
char *p = (unsigned char *)value;
Atom *a = (Atom *)value;
if (*type == 0 || *type == XT_CONVERT_FAIL)
return;
printf("target %s ", XGetAtomName(dpy, (Atom)client_data));
printf("type %s ", XGetAtomName(dpy, *type));
printf("length %lu ", *length);
printf("format %d: ", *format);
switch (*type) {
case XA_ATOM:
for (i = 0; i < *length; i++)
printf("%s ", XGetAtomName(dpy, a[i]));
printf("\n");
break;
case XA_INTEGER:
for (i = 0; i < *length; i++)
printf("%d ", *((int *)value + i));
printf("\n");
break;
case XA_WINDOW:
for (i = 0; i < *length; i++)
printf("0x%08x ", *((unsigned int *)value + i));
printf("\n");
break;
case XA_STRING:
printf("%s\n", (char *)value);
break;
default:
if (*type == XA_UTF8_STRING(dpy))
wprintf(L"u\"%s\"\n", (char *)value);
else if (*type == XA_NET_ADDRESS(dpy))
printf("%u.%u.%u.%u\n", *(unsigned char *)value,
*((unsigned char *)value + 1),
*((unsigned char *)value + 2),
*((unsigned char *)value + 3));
else {
for (i = 0; i < *length; i++)
printf("%02hhx ", p[i]);
printf("\n");
}
break;
}
}
static void
request_selection(Widget w, XtPointer client_data, XtPointer call_data)
{
Display *dpy = XtDisplay(w);
if (targets == NULL) {
XtGetSelectionValue(w, XA_PRIMARY, XA_TARGETS(dpy),
targets_cb, client_data, XtLastTimestampProcessed(dpy));
} else {
for (int i = 0; i < num_targets; i++) {
XtGetSelectionValue(w, XA_PRIMARY, targets[i],
sel_cb, (void *)targets[i],
XtLastTimestampProcessed(dpy));
}
}
}
int
main(int argc, char *argv[])
{
Widget top, req;
top = XtInitialize(argv[0], "TSel", NULL, 0, &argc, argv);
req = XtCreateManagedWidget("Get Selection", commandWidgetClass, top,
NULL, 0);
XtAddCallback(req, XtNcallback, request_selection, NULL);
XtRealizeWidget(top);
//XtGetSelectionValue(req, XA_PRIMARY, XA_TARGETS(XtDisplay(req)),
// targets_cb, NULL, XtLastTimestampProcessed(XtDisplay(req)));
XtMainLoop();
printf("done\n");
return 0;
}
--
Matthieu Herrb