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