//**************************************************************************/
/* */
/* This is the X-select application for the Notebook X-Windows demos. */
/* It retrieves the contexts via the XSELinux OM and the selected item */
/* (Hello World) is selected and given to the calling X-paste application.*/
/* */
/* Copyright (C) 2010 Richard Haines */
/* */
/* This program is free software: you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation, either version 3 of the License, or */
/* (at your option) any later version. */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see . */
/* */
/**************************************************************************/
#include
#include
#include
#include
#include
#include
#include
#define ENFORCING 1
// The Error handler functions are in XSELinuxOMFunctions.c
extern int CatchXErrorHandler ();
extern int CatchXreplyErrorHandler ();
//Hold the opcode from the XQueryExtension call in XSELinuxOMFunctions.c
extern int X_SELinuxExtensionOpcode;
// Set output to stdout, but allow output to a file with option 'o'
// Declared here as used by functions in XSELinuxOMFunctions.c to output info
FILE *outputPtr;
int main (int argc, char **argv)
{
// SELinux Context
security_context_t domainContext;
int result;
unsigned char buffer [] = "Hello World";
int event, error;
Window Sown;
XEvent xevent;
XTextProperty windowName;
XSelectionRequestEvent *request_event;
char windowNameString [100] = " ";
char *windowNamePtr;
// Set output to stdout but allow output to a file with command line option
outputPtr = stdout;
// Use argv [1] as the filename for output
if (argc == 2) {
if ((outputPtr = fopen (argv [1], "w")) == NULL) {
fprintf (stderr, "Cannot open output file %s\n", argv [1]);
outputPtr = stdout;
}
else
printf("\nOutput to file: %s\n", argv [1]);
}
// Check if enforcing or not
if (security_getenforce () == ENFORCING)
fprintf (outputPtr, "SELinux is in Enforcing mode\n");
else
fprintf (outputPtr, "SELinux is in Permissive mode\n");
// Get a display handle
Display *dpy = XOpenDisplay(NULL);
// Get the SELinux Extension opcode
if (!XQueryExtension (dpy, "SELinux", &X_SELinuxExtensionOpcode, &event, &error)) {
perror ("XSELinux extension not available");
exit (1);
}
else {
fprintf (outputPtr, "\n***** Display Initial Window Information ******\n");
fprintf (outputPtr, "\nXQueryExtension for XSELinux Extension - Opcode: %d Events: %d Error: %d \n", X_SELinuxExtensionOpcode, event, error);
}
// Have XSELinux Object Manager
// Set our own handler for errors as the default displays error and exits.
XSetErrorHandler (CatchXErrorHandler);
// Set our own handler for _XReply errors.
XExtCodes *codes = XInitExtension (dpy, "SELinux");
XESetError (dpy, codes->extension, CatchXreplyErrorHandler);
// Now open a window
Window w = XCreateSimpleWindow (dpy, DefaultRootWindow(dpy), 0, 0, 500, 50, 0, 0, 0);
// Get and print Client context information
if (result = getcon (&domainContext) < 0) {
perror ("Could not get Client context");
exit (1);
}
fprintf (outputPtr, "\nlibselinux getcon - Domain Context: %s for WinID: %d\n", domainContext, w);
sprintf (windowNameString, "%s - %s", argv[0], domainContext);
// Get the SELinux OM Version
fprintf (outputPtr, "\nCalling SELinuxQueryVersion (0) for this display:\n");
SELinuxQueryVersion (dpy);
fprintf (outputPtr, "\nCalling SELinuxListProperties (14) before Drawing Window (WinID: %d):\n", w);
SELinuxListProperties (dpy, w);
// Show the app name and SELinux context in the Window
windowNamePtr = windowNameString;
if (XStringListToTextProperty ((char **)&windowNamePtr, 1, &windowName) == 0) {
perror ("Structure allocation for windowName failed");
exit (1);
}
XSetWMProperties (dpy, w, &windowName, NULL, NULL, 0, NULL, NULL, NULL);
freecon (domainContext);
XSelectInput (dpy, w, StructureNotifyMask);
XMapWindow (dpy, w);
XFlush (dpy);
// This function is called to display the start-up context info.
DisplayInitialContextInfo (dpy, w);
// This function can be called to set any context info using the
// SELinuxSet... functions.
SetContextTest (dpy);
XFlush (dpy);
fflush (outputPtr);
// Set the selection owner to our wndow
XSetSelectionOwner (dpy, XA_PRIMARY, w, CurrentTime);
while (1) {
// Uncomment the XSetSelectionOwner here to ensure the app always selects
XSetSelectionOwner (dpy, XA_PRIMARY, w, CurrentTime);
printf ("WinID: %d waiting for SelectionRequest event\n", (Window)w);
XNextEvent (dpy, &xevent);
if (xevent.type == SelectionRequest) {
request_event=&(xevent.xselectionrequest);
printf ("Have SelectionRequest event\n");
// Comment out DisplaySelectionContextInfo to stop screen clutter:
DisplaySelectionContextInfo (dpy, w);
if (request_event->target == XA_STRING)
XChangeProperty (dpy, request_event->requestor, request_event->property, XA_STRING, 8, PropModeReplace, buffer, sizeof (buffer));
}
}
}
/**************************************************************************/
/* */
/* These functions display or set (optional) information using the */
/* XSELinux functions. They have been moved here to avoid cluttering the */
/* X code that selects the data. */
/* */
/**************************************************************************/
// This function is called to display the start-up context info for tests.
int DisplayInitialContextInfo (Display *dpy, Window w)
{
XIDeviceInfo *devices, device;
int ndevices, counter;
fprintf (outputPtr, "\nCalling SELinuxGetWindowCreateContext (6) for this display:\n");
SELinuxGetWindowCreateContext (dpy);
fprintf (outputPtr, "\nCalling SELinuxGetClientContext (22) for this Resource (WinID: %d):\n", w);
SELinuxGetClientContext (dpy, w);
fprintf (outputPtr, "\nCalling SELinuxGetWindowContext (7) for this Window (WinID: %d):\n", w);
SELinuxGetWindowContext (dpy, w);
// Do Device stuff
fprintf (outputPtr, "\nCalling SELinuxGetDeviceCreateContext (2) for this display:\n");
SELinuxGetDeviceCreateContext (dpy);
fprintf (outputPtr, "\nCalling SELinuxGetDeviceContext (4) for this display:\n", w);
devices = XIQueryDevice(dpy, XIAllDevices, &ndevices);
for (counter = 0; counter < ndevices; counter++) {
device = devices [counter];
fprintf (outputPtr, "\nDevice %s is a ", device.name);
switch (device.use) {
case XIMasterPointer: fprintf (outputPtr, "master pointer\n");
break;
case XIMasterKeyboard: fprintf (outputPtr, "master keyboard\n");
break;
case XISlavePointer: fprintf (outputPtr, "slave pointer\n");
break;
case XISlaveKeyboard: fprintf (outputPtr, "slave keyboard\n");
break;
case XIFloatingSlave: fprintf (outputPtr, "floating slave\n");
break;
}
SELinuxGetDeviceContext (dpy, device.deviceid);
}
XIFreeDeviceInfo (devices);
// Do Properties
fprintf (outputPtr, "\nCalling SELinuxGetPropertyCreateContext (9) this display:\n");
SELinuxGetPropertyCreateContext (dpy);
fprintf (outputPtr, "\nCalling SELinuxGetPropertyUseContext (11) for this display:\n");
SELinuxGetPropertyUseContext (dpy);
fprintf (outputPtr, "\nCalling SELinuxListProperties (14) after Drawing Window (WinID: %d):\n", w);
SELinuxListProperties (dpy, w);
// Do Selections
fprintf (outputPtr, "\nCalling SELinuxGetSelectionCreateContext (16) for this display:\n");
SELinuxGetSelectionCreateContext (dpy);
fprintf (outputPtr, "\nCalling SELinuxGetSelectionUseContext (18) for this display:\n");
SELinuxGetSelectionUseContext (dpy);
fprintf (outputPtr, "\nCalling SELinuxListSelections (21) for this display:\n");
SELinuxListSelections (dpy);
}
// This function is called to display the context info when selection made for tests.
int DisplaySelectionContextInfo (Display *dpy, Window w)
{
fprintf (outputPtr, "\n***** Display Selection Window Information ******\n");
// Call the SELinux extension codes For Selections - with XA_PRIMARY)
fprintf (outputPtr, "\nCalling SELinuxGetSelectionContext (19) with XA_PRIMARY for this Window (WinID: %d)\n", w);
SELinuxGetSelectionContext (dpy, XA_PRIMARY);
fprintf (outputPtr, "\nCalling SELinuxGetSelectionDataContext (20) with XA_PRIMARY for this Window (WinID: %d)\n", w);
SELinuxGetSelectionDataContext (dpy, XA_PRIMARY);
// Call the SELinux extension codes For Properties - with XA_WM_NAME)
fprintf (outputPtr, "\nCalling SELinuxGetPropertyContext (12) with WM_NAME for this Window:\n");
SELinuxGetPropertyContext (dpy, w, XA_WM_NAME);
fprintf (outputPtr, "\nCalling SELinuxGetPropertyDataContext (13) with WM_NAME for this Window:\n");
SELinuxGetPropertyDataContext (dpy, w, XA_WM_NAME);
fflush (outputPtr);
}
// This function can be called to set any context info for tests.
int SetContextTest (Display *dpy)
{
/*
fprintf (outputPtr, "\nAdding any compiled SELinuxSet... function context entries\n");
// Allows Select / Paste
fprintf (outputPtr, "\nCalling SELinuxSetWindowCreateContext (5) for this display\n");
SELinuxSetWindowCreateContext (dpy, "user_u:object_r:unconfined_t");
fprintf (outputPtr, "\nCalling SELinuxGetWindowCreateContext (6) for this display:\n");
SELinuxGetWindowCreateContext (dpy);
fprintf (outputPtr, "\nCalling SELinuxSetPropertyCreateContext (8) for this display\n");
SELinuxSetPropertyCreateContext (dpy, "user_u:object_r:unconfined_t");
fprintf (outputPtr, "\nCalling SELinuxGetPropertyCreateContext (9) for this display:\n");
SELinuxGetPropertyCreateContext (dpy);
// This one returns BadMatch with X-paste on Property Atom WM_NAME even with setenforce = 1
fprintf (outputPtr, "\nCalling SELinuxSetPropertyUseContext (10) for this display\n");
SELinuxSetPropertyUseContext (dpy, "user_u:object_r:unconfined_t");
fprintf (outputPtr, "\nCalling SELinuxGetPropertyUseContext (11) for this display:\n");
SELinuxGetPropertyUseContext (dpy);
fprintf (outputPtr, "\nCalling SELinuxSetSelectionCreateContext (15) for this display\n");
SELinuxSetSelectionCreateContext (dpy, "user_u:object_r:unconfined_t");
fprintf (outputPtr, "\nCalling SELinuxGetSelectionCreateContext (16) for this display:\n");
SELinuxGetSelectionCreateContext (dpy);
fprintf (outputPtr, "\nCalling SELinuxSetSelectionUseContext (17) for this display\n");
// SELinuxSetSelectionUseContext (dpy, "user_u:object_r:unconfined_t");
SELinuxSetSelectionUseContext (dpy, "user_u:object_r:x_select_paste_t");
fprintf (outputPtr, "\nCalling SELinuxGetSelectionUseContext (18) for this display:\n");
SELinuxGetSelectionUseContext (dpy);
fprintf (outputPtr, "\nEnd SELinuxSet... functions\n");
*/
}