/**************************************************************************/
/* */
/* This is the X-paste application for the Notebook X-Windows demos. */
/* It retrieves the contexts via the XSELinux OM and the selected item */
/* from the X-select 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
#include
#define ENFORCING 1
// The Error handler functions are in XSELinuxOMFunctions.c
extern int CatchXErrorHandler ();
extern int CatchXreplyErrorHandler ();
// SELinux Context stuff
security_context_t domainContext;
//Hold the opcode from the XQueryExtension call
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)
{
int propertyFormat, result, counter;
unsigned long propertyItems, stringLength, holder;
char *selectedData;
int event, error;
XEvent xevent;
Atom propertyType;
Window Sown;
XTextProperty windowName;
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);
XSelectInput (dpy, w, StructureNotifyMask+ExposureMask);
while (1) {
// XGetSelectionOwner returns the current owner of the Selection in Sown, or None if no selections made
Sown = XGetSelectionOwner (dpy, XA_PRIMARY);
fprintf (outputPtr, "\nWaiting for Selection Owner\n");
if (outputPtr != stdout)
printf("\nWaiting for Selection Owner\n");
if (Sown != None) {
// XConvertSelection converts the specified selection to the specified target type
XConvertSelection (dpy,
XA_PRIMARY, // Selection atom
XA_STRING, // Target atom
XA_STRING, // Property name
Sown, // The current owner
CurrentTime);
XFlush (dpy);
// This function is called to display the context info when selection made for tests.
DisplaySelectionContextInfo (dpy, w, Sown);
// Query how much data to retrieve
result = XGetWindowProperty (dpy, Sown,
XA_STRING, // Atom Property name
0, 0, // offset & length set to zero as this is a query
0, // Do not delete
XA_STRING, // For this test require a STRING
&propertyType, // return property type
&propertyFormat, // returned property format
&propertyItems, // returned number items
&stringLength, // number of bytes to read
(unsigned char **)&selectedData); // Returned data
if (result == Success) {
// Check if selected text is present (X-select running or if in unconfined_t
// then could be any selected text)
if (stringLength > 0) {
fprintf (outputPtr, "\nThis WinID: %d has data selected by WinID: %d\n",
(Window)w , (Window)Sown);
if (outputPtr != stdout) {
printf("\nThis WinID: %d has data selected by WinID: %d\n",
(Window)w , (Window)Sown);
fflush (outputPtr);
}
result = XGetWindowProperty (dpy, Sown, XA_STRING, 0, stringLength,
0, AnyPropertyType, &propertyType,
&propertyFormat,&propertyItems,
&holder, (unsigned char **)&selectedData);
if (result == Success) {
fprintf (outputPtr, "The data selected is \"%s\" with Atom Name: %s and a length of %d bytes\n", selectedData, (XGetAtomName (dpy, propertyType)), stringLength);
XFree (selectedData);
}
else fprintf (outputPtr, "Failed to read selected data\n");
}
}
}
fflush (outputPtr);
sleep(2);
}
}
/**************************************************************************/
/* */
/* These functions display or set (optional) information using the */
/* XSELinux functions. They have been moved here to avoid cluttering the */
/* code that pastes 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 detected.
int DisplaySelectionContextInfo (Display *dpy, Window w, Window Sown)
{
fprintf (outputPtr, "\n***** Have Selection Owner so display Window ******\n");
fprintf (outputPtr, "***** Selection & Property Information ******\n");
// Call the SELinux extension codes For Selections - with XA_PRIMARY)
fprintf (outputPtr, "\nCalling SELinuxGetSelectionContext (19) with XA_PRIMARY for Selection Owner Window (WinID: %d)\n", Sown);
SELinuxGetSelectionContext (dpy, XA_PRIMARY);
fprintf (outputPtr, "\nCalling SELinuxGetSelectionDataContext (20) with XA_PRIMARY for Selection Owner Window (WinID: %d)\n", Sown);
SELinuxGetSelectionDataContext (dpy, 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 Property Owner Window:\n");
SELinuxGetPropertyContext (dpy, Sown, XA_WM_NAME);
fprintf (outputPtr, "\nCalling SELinuxGetPropertyDataContext (13) with WM_NAME for Property Owner Window:\n");
SELinuxGetPropertyDataContext (dpy, Sown, 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);
}
// 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");
fprintf (outputPtr, "\nCalling SELinuxGetSelectionUseContext (18) for this display:\n");
SELinuxGetSelectionUseContext (dpy);
fprintf (outputPtr, "\nEnd SELinuxSet... functions\n");
*/
}