/**************************************************************************/ /* */ /* 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"); */ }