/**************************************************************************/ /* */ /* The XSELinux test application for the Notebook X-Windows demos. */ /* It makes use of the functions in XSELinuxOMFunctions.c. */ /* They are used to retrieve contexts and add them as required for the */ /* X-Windows Object Manager test examples. */ /* */ /* 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 #include "../x-common/Xlib-selinux.h" #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; // Display the selection menu int Menu () { printf ("\nXSELinux Functions:\n"); printf ("0) QueryVersion\n"); printf ("1) SetDeviceCreateContext (context) 2) GetDeviceCreateContext\n"); printf ("3) SetDeviceContext (device+context) 4) GetDeviceContext (lists all)\n"); printf ("5) SetWindowCreateContext (context) 6) GetWindowCreateContext\n"); printf ("7) GetWindowContext (win_id)\n"); printf ("8) SetPropertyCreateContext (context) 9) GetPropertyCreateContext\n"); printf ("10) SetPropertyUseContext (context) 11) GetPropertyUseContext\n"); printf ("12) GetPropertyContext (win_id+atom) 13) GetPropertyDataContext (win_id+atom)\n"); printf ("14) ListProperties (win_id)\n"); printf ("15) SetSelectionCreateContext (context) 16) GetSelectionCreateContext\n"); printf ("17) SetSelectionUseContext (context) 18) GetSelectionUseContext\n"); printf ("19) GetSelectionContext (atom) 20) GetSelectionDataContext (atom)\n"); printf ("21) ListSelections\n"); printf ("22) GetClientContext (resource_id)\n"); printf ("\n"); printf ("d) Display domain context h) Help\n"); printf ("m) Display menu o) Set output file\n"); printf ("q) Quit w) Display windowID\n"); return 0; } // Display info int Help () { printf ("X-setest information:\n"); printf ("The SELinux X-Windows Object Manager (XSelinux) has a number of built-in\n"); printf ("functions that can be called by SELinux-aware applications to Get.. and\n"); printf ("Set.. information. This application will allow each of these functions to be\n"); printf ("called and display any information and/or error messages that are generated.\n"); printf ("\nThe functions 12, 13, 19, 20 & 22 return an XError of BadAlloc when access\n"); printf ("is denied and generates a USER_AVC entry in the audit.log.\n"); printf ("Note: XErrors are checked first and not logged in audit.log, only AVC errors\n"); printf ("with entries such as \"for request=SELinux:SELinuxGetClientContext\".\n"); printf ("\nWhen entering Atom names, they are checked for validity, however they are NOT\n"); printf ("checked to see if they are valid for the specific function (e.g. you can enter\n"); printf ("PRIMARY for a GetProperty... function, but it will fail with BadMatch).\n"); printf ("\nNote that Window and Resource IDs entered are not checked by X-setest and if\n"); printf ("incorrect the function will fail with BadMatch.\n"); printf ("\nThe 'o' option allows an output file to be specified to log the session\n"); printf ("however, only minimum information is then displayed on the screen.\n"); } int main (int argc, char **argv) { char answer1 [80], answer2 [80], outFileName [80], windowNameString [100] = " "; int result, counter, ndevices; unsigned long resourceID, deviceID; int event, error, index; security_context_t domainContext; Atom atomName; Window windowID; XTextProperty windowName; XIDeviceInfo *devices, device; char *windowNamePtr; // Set output to stdout, but allow output to a file with option 'o' outputPtr = stdout; // 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 printf ("\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); } printf ("\nlibselinux getcon - Domain Context: %s for WinID: %d\n", domainContext, w); sprintf (windowNameString, "%s - %s", argv[0], domainContext); // 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); // Display menu Menu (); // and wait for input for (;;) { if (security_getenforce () == ENFORCING) printf ("SELinux is currently in Enforcing mode\n"); else printf ("SELinux is currently in Permissive mode\n"); printf ("\nSelect a function or \'m\' to redisplay the menu: "); fgets (answer1, sizeof(answer1), stdin); switch (answer1 [0]) { case 'd': fprintf (outputPtr, "This Domain Context: %s\n", domainContext); break; case 'h': Help (); break; case 'm': Menu (); break; case 'q': fflush (outputPtr); exit (0); break; case 'w': fprintf (outputPtr, "This WindowID: %d\n", w); break; case 'o': printf ("\nFilename for output or return for screen output: "); fgets (outFileName, sizeof(outFileName), stdin); outFileName [strlen (outFileName) - 1] = '\0'; if (strlen (outFileName) == 0) outputPtr = stdout; else if ((outputPtr = fopen (outFileName, "w")) == NULL) { fprintf (stderr, "Cannot open output file %s\n", outFileName); outputPtr = stdout; } if (outputPtr != stdout) printf("\nOutput to file: %s\n", outFileName); if (security_getenforce () == ENFORCING) fprintf (outputPtr, "SELinux is in Enforcing mode\n"); else fprintf (outputPtr, "SELinux is in Permissive mode\n"); break; default: index = atoi (answer1); switch (index) { case 0: fprintf (outputPtr, "\nCalling SELinuxQueryVersion (0) for this display:\n"); SELinuxQueryVersion (dpy); break; case 1: // Get Context printf ("Enter Device Create Context: "); fgets (answer1, sizeof(answer1), stdin); // Remove cr answer1 [strlen (answer1) - 1] = 0; fprintf (outputPtr, "\nCalling SELinuxSetDeviceCreateContext (1) for this display\n"); SELinuxSetDeviceCreateContext (dpy, answer1); break; case 2: fprintf (outputPtr, "\nCalling SELinuxGetDeviceCreateContext (2) for this display:\n"); SELinuxGetDeviceCreateContext (dpy); break; case 3: // Get Context printf ("Enter Device Context: "); fgets (answer1, sizeof(answer1), stdin); answer1 [strlen (answer1) - 1] = 0; // Get Device ID printf("Enter Device ID: "); fgets (answer2, sizeof(answer2), stdin); deviceID = atoi (answer2); fprintf (outputPtr, "\nCalling SELinuxSetDeviceContext (3) for this display\n"); SELinuxSetDeviceContext (dpy, answer1, deviceID); break; case 4: 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); break; case 5: // Get Context printf ("Enter Window Create Context: "); fgets (answer1, sizeof(answer1), stdin); answer1 [strlen (answer1) - 1] = 0; fprintf (outputPtr, "\nCalling SELinuxSetWindowCreateContext (5) for this display\n"); SELinuxSetWindowCreateContext (dpy, answer1); break; case 6: fprintf (outputPtr, "\nCalling SELinuxGetWindowCreateContext (6) for this display:\n"); SELinuxGetWindowCreateContext (dpy); break; case 7: // Get WinID: printf ("Enter Window ID or return for this window: "); fgets (answer1, sizeof(answer1), stdin); answer1 [strlen (answer1) - 1] = 0; if (answer1 [0] == 0) windowID = w; else windowID = (atoi (answer1)); fprintf (outputPtr, "\nCalling SELinuxGetWindowContext (7) for Window (WinID: %d):\n", windowID); SELinuxGetWindowContext (dpy, windowID); break; case 8: // Get Context printf ("Enter Property Create Context: "); fgets (answer1, sizeof(answer1), stdin); answer1 [strlen (answer1) - 1] = 0; fprintf (outputPtr, "\nCalling SELinuxSetPropertyCreateContext (8) for this display\n"); SELinuxSetPropertyCreateContext (dpy, answer1); break; case 9: fprintf (outputPtr, "\nCalling SELinuxGetPropertyCreateContext (9) this display:\n"); SELinuxGetPropertyCreateContext (dpy); break; case 10: // Get Context printf ("Enter Property Use Context: "); fgets (answer1, sizeof(answer1), stdin); answer1 [strlen (answer1) - 1] = 0; fprintf (outputPtr, "\nCalling SELinuxSetPropertyUseContext (10) for this display\n"); SELinuxSetPropertyUseContext (dpy, answer1); break; case 11: fprintf (outputPtr, "\nCalling SELinuxGetPropertyUseContext (11) for this display:\n"); SELinuxGetPropertyUseContext (dpy); break; case 12: // Get WinID: printf ("Enter Window ID or return for this window: "); fgets (answer1, sizeof(answer1), stdin); answer1 [strlen (answer1) - 1] = 0; if (answer1 [0] == 0) windowID = w; else windowID = (atoi (answer1)); // Get ATOM printf("Enter Property Atom Name: "); fgets (answer1, sizeof(answer1), stdin); answer1 [strlen (answer1) - 1] = 0; atomName = XInternAtom (dpy, answer1, xTrue); if (atomName == None) { printf ("Invalid Atom Name\n"); break; } fprintf (outputPtr, "\nCalling SELinuxGetPropertyContext (12) with %s for Window (WinID: %d):\n", (XGetAtomName (dpy, atomName)), windowID); SELinuxGetPropertyContext (dpy, windowID, atomName); break; case 13: // Get WinID: printf ("Enter Window ID or return for this window: "); fgets (answer1, sizeof(answer1), stdin); answer1 [strlen (answer1) - 1] = 0; if (answer1 [0] == 0) windowID = w; else windowID = (atoi (answer1)); // Get ATOM printf ("Enter Property Atom Name: "); fgets (answer1, sizeof(answer1), stdin); answer1 [strlen (answer1) - 1] = 0; atomName = XInternAtom (dpy, answer1, xTrue); if (atomName == None) { printf ("Invalid Atom Name\n"); break; } fprintf (outputPtr, "\nCalling SELinuxGetPropertyDataContext (13) with %s for Window (WinID: %d):\n", (XGetAtomName (dpy, atomName)), windowID); SELinuxGetPropertyDataContext (dpy, windowID, atomName); break; case 14: // Get WinID: printf ("Enter Window ID or return for this window: "); fgets (answer1, sizeof(answer1), stdin); answer1 [strlen (answer1) - 1] = 0; if (answer1 [0] == 0) windowID = w; else windowID = (atoi (answer1)); fprintf (outputPtr, "\nCalling SELinuxListProperties (14) for Window (WinID: %d):\n", windowID); SELinuxListProperties (dpy, windowID); break; case 15: // Get Context printf ("Enter Selection Create Context: "); fgets (answer1, sizeof(answer1), stdin); answer1 [strlen(answer1) - 1] = 0; fprintf (outputPtr, "\nCalling SELinuxSetSelectionCreateContext (15) for this display\n"); SELinuxSetSelectionCreateContext (dpy, answer1); break; case 16: fprintf (outputPtr, "\nCalling SELinuxGetSelectionCreateContext (16) for this display:\n"); SELinuxGetSelectionCreateContext (dpy); break; case 17: // Get Context printf ("Enter Selection Use Context: "); fgets (answer1, sizeof(answer1), stdin); answer1 [strlen (answer1) - 1] = 0; fprintf (outputPtr, "\nCalling SELinuxSetSelectionUseContext (17) for this display\n"); SELinuxSetSelectionUseContext (dpy, answer1); break; case 18: fprintf (outputPtr, "\nCalling SELinuxGetSelectionUseContext (18) for this display:\n"); SELinuxGetSelectionUseContext (dpy); break; case 19: // Get ATOM printf ("Enter Selection Atom Name: "); fgets (answer1, sizeof(answer1), stdin); answer1 [strlen (answer1) - 1] = 0; atomName = XInternAtom (dpy, answer1, xTrue); if (atomName == None) { printf ("Invalid Atom Name\n"); break; } fprintf (outputPtr, "\nCalling SELinuxGetSelectionContext (19) with %s for this display\n", (XGetAtomName (dpy, atomName))); SELinuxGetSelectionContext (dpy, atomName); break; case 20: // Get ATOM printf ("Enter Selection Atom Name: "); fgets (answer1, sizeof(answer1), stdin); answer1 [strlen (answer1) - 1] = 0; atomName = XInternAtom (dpy, answer1, xTrue); if (atomName == None) { printf ("Invalid Atom Name\n"); break; } fprintf (outputPtr, "\nCalling SELinuxGetSelectionDataContext (20) with %s for this Window:\n", (XGetAtomName (dpy, atomName))); SELinuxGetSelectionDataContext (dpy, atomName); break; case 21: fprintf (outputPtr, "\nCalling SELinuxListSelections (21) for this display:\n"); SELinuxListSelections (dpy); break; case 22: printf ("Enter Resource ID or return for this window: "); fgets (answer1, sizeof(answer1), stdin); answer1 [strlen (answer1) - 1] = 0; if (answer1 [0] == 0) resourceID = w; else resourceID = (atoi (answer1)); fprintf (outputPtr, "\nCalling SELinuxGetClientContext (22) for this Resource: %d\n", resourceID); SELinuxGetClientContext (dpy, resourceID); break; default: printf ("\nInvalid Selection\n"); Menu (); break; } } } }