/**************************************************************** * secpol_xml2bin.c * * Copyright (C) 2005 IBM Corporation * * Author: Reiner Sailer * * Maintained: * Reiner Sailer * Ray Valdez * * 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, version 2 of the * License. * * sHype policy translation tool. This tool takes an XML * policy specification as input and produces a binary * policy file that can be loaded into Xen through the * ACM operations (xensec_tool loadpolicy) interface or at * boot time (grub module parameter) * * indent -i4 -kr -nut */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "secpol_xml2bin.h" #define DEBUG 0 #define NULL_LABEL_NAME "__NULL_LABEL__" /* primary / secondary policy component setting */ enum policycomponent { CHWALL, STE, NULLPOLICY } primary = NULLPOLICY, secondary = NULLPOLICY; /* general list element for ste and chwall type queues */ struct type_entry { TAILQ_ENTRY(type_entry) entries; char *name; /* name of type from xml file */ type_t mapping; /* type mapping into 16bit */ }; TAILQ_HEAD(tailhead, type_entry) ste_head, chwall_head; /* general list element for all label queues */ enum label_type { VM, RES, ANY }; struct ssid_entry { TAILQ_ENTRY(ssid_entry) entries; char *name; /* label name */ enum label_type type; /* type: VM / RESOURCE LABEL */ u_int32_t num; /* ssid or referenced ssid */ int is_ref; /* if this entry references earlier ssid number */ unsigned char *row; /* index of types (if not a reference) */ }; TAILQ_HEAD(tailhead_ssid, ssid_entry) ste_ssid_head, chwall_ssid_head, conflictsets_head; struct ssid_entry *current_chwall_ssid_p = NULL; struct ssid_entry *current_ste_ssid_p = NULL; struct ssid_entry *current_conflictset_p = NULL; /* which label to assign to dom0 during boot */ char *bootstrap_label; u_int32_t max_ste_ssids = 0; u_int32_t max_chwall_ssids = 0; u_int32_t max_chwall_labels = 0; u_int32_t max_ste_labels = 0; u_int32_t max_conflictsets = 0; char *current_ssid_name; /* store name until structure is allocated */ char *current_conflictset_name; /* store name until structure is allocated */ /* dynamic list of type mappings for STE */ u_int32_t max_ste_types = 0; /* dynamic list of type mappings for CHWALL */ u_int32_t max_chwall_types = 0; /* dynamic list of conflict sets */ int max_conflict_set = 0; /* which policies are defined */ int have_ste = 0; int have_chwall = 0; /* input/output file names */ char *policy_filename = NULL, *binary_filename = NULL, *mapping_filename = NULL, *schema_filename = NULL; char *policy_reference_name = NULL; void walk_labels(xmlNode * start, xmlDocPtr doc, unsigned long state); void usage(char *prg) { printf("Usage: %s [OPTIONS] POLICYNAME\n", prg); printf ("POLICYNAME is the directory name within the policy directory\n"); printf ("that contains the policy files. The default policy directory\n"); printf("is '%s' (see the '-d' option below to change it)\n", POLICY_DIR); printf ("The policy files contained in the POLICYNAME directory must be named:\n"); printf("\tPOLICYNAME-security_policy.xml\n"); printf("\tPOLICYNAME-security_label_template.xml\n\n"); printf("OPTIONS:\n"); printf("\t-d POLICYDIR\n"); printf ("\t\tUse POLICYDIR as the policy directory. This directory must contain\n"); printf("\t\tthe policy schema file 'security_policy.xsd'\n"); exit(EXIT_FAILURE); } /***************** policy-related parsing *********************/ char *type_by_mapping(struct tailhead *head, u_int32_t mapping) { struct type_entry *np; for (np = head->tqh_first; np != NULL; np = np->entries.tqe_next) if (np->mapping == mapping) return np->name; return NULL; } struct type_entry *lookup(struct tailhead *head, char *name) { struct type_entry *np; for (np = head->tqh_first; np != NULL; np = np->entries.tqe_next) if (!(strcmp(np->name, name))) return np; return NULL; } /* enforces single-entry lists */ int add_entry(struct tailhead *head, char *name, type_t mapping) { struct type_entry *e; if (lookup(head, name)) { printf("Error: Type >%s< defined more than once.\n", name); return -EFAULT; /* already in the list */ } if (!(e = malloc(sizeof(struct type_entry)))) return -ENOMEM; e->name = name; e->mapping = mapping; TAILQ_INSERT_TAIL(head, e, entries); return 0; } int totoken(char *tok) { int i; for (i = 0; token[i] != NULL; i++) if (!strcmp(token[i], tok)) return i; return -EFAULT; } /* conflictsets use the same data structure as ssids; since * they are similar in structure (set of types) */ int init_next_conflictset(void) { struct ssid_entry *conflictset = malloc(sizeof(struct ssid_entry)); if (!conflictset) return -ENOMEM; conflictset->name = current_conflictset_name; conflictset->num = max_conflictsets++; conflictset->is_ref = 0; /* n/a for conflictsets */ /** * row: allocate one byte per type; * [i] != 0 --> mapped type >i< is part of the conflictset */ conflictset->row = malloc(max_chwall_types); if (!conflictset->row) return -ENOMEM; memset(conflictset->row, 0, max_chwall_types); TAILQ_INSERT_TAIL(&conflictsets_head, conflictset, entries); current_conflictset_p = conflictset; return 0; } int register_type(xmlNode * cur_node, xmlDocPtr doc, unsigned long state) { xmlChar *text; struct type_entry *e; text = xmlNodeListGetString(doc, cur_node->xmlChildrenNode, 1); if (!text) { printf("Error reading type name!\n"); return -EFAULT; } switch (state) { case XML2BIN_stetype_S: if (add_entry(&ste_head, (char *) text, max_ste_types)) { xmlFree(text); return -EFAULT; } max_ste_types++; break; case XML2BIN_chwalltype_S: if (add_entry(&chwall_head, (char *) text, max_chwall_types)) { xmlFree(text); return -EFAULT; } max_chwall_types++; break; case XML2BIN_conflictsettype_S: /* a) search the type in the chwall_type list */ e = lookup(&chwall_head, (char *) text); if (e == NULL) { printf("CS type >%s< not a CHWALL type.\n", text); xmlFree(text); return -EFAULT; } /* b) add type entry to the current cs set */ if (current_conflictset_p->row[e->mapping]) { printf ("ERROR: Double entry of type >%s< in conflict set %d.\n", text, current_conflictset_p->num); xmlFree(text); return -EFAULT; } current_conflictset_p->row[e->mapping] = 1; break; default: printf("Incorrect type environment (state = %lx, text = %s).\n", state, text); xmlFree(text); return -EFAULT; } return 0; } void set_component_type(xmlNode * cur_node, enum policycomponent pc) { xmlChar *order; if ((order = xmlGetProp(cur_node, (xmlChar *) PRIMARY_COMPONENT_ATTR_NAME))) { if (strcmp((char *) order, PRIMARY_COMPONENT)) { printf("ERROR: Illegal attribut value >order=%s<.\n", (char *) order); xmlFree(order); exit(EXIT_FAILURE); } if (primary != NULLPOLICY) { printf("ERROR: Primary Policy Component set twice!\n"); exit(EXIT_FAILURE); } primary = pc; xmlFree(order); } } void walk_policy(xmlNode * start, xmlDocPtr doc, unsigned long state) { xmlNode *cur_node = NULL; int code; for (cur_node = start; cur_node; cur_node = cur_node->next) { if ((code = totoken((char *) cur_node->name)) < 0) { printf("Unknown token: >%s<. Aborting.\n", cur_node->name); exit(EXIT_FAILURE); } switch (code) { /* adjust state to new state */ case XML2BIN_SECPOL: case XML2BIN_STETYPES: case XML2BIN_CHWALLTYPES: case XML2BIN_CONFLICTSETS: case XML2BIN_POLICYHEADER: walk_policy(cur_node->children, doc, state | (1 << code)); break; case XML2BIN_POLICYNAME: /* get policy reference name .... */ if (state != XML2BIN_PN_S) { printf("ERROR: >Url< >%s< out of context.\n", (char *) xmlNodeListGetString(doc, cur_node-> xmlChildrenNode, 1)); exit(EXIT_FAILURE); } policy_reference_name = (char *) xmlNodeListGetString(doc, cur_node->xmlChildrenNode, 1); if (!policy_reference_name) { printf("ERROR: empty >policy reference name (Url)children, doc, state | (1 << code)); break; case XML2BIN_CHWALL: if (WRITTEN_AGAINST_ACM_CHWALL_VERSION != ACM_CHWALL_VERSION) { printf ("ERROR: This program was written against another CHWALL version.\n"); exit(EXIT_FAILURE); } have_chwall = 1; set_component_type(cur_node, CHWALL); walk_policy(cur_node->children, doc, state | (1 << code)); break; case XML2BIN_CSTYPE: current_conflictset_name = (char *) xmlGetProp(cur_node, (xmlChar *) "name"); if (!current_conflictset_name) current_conflictset_name = ""; if (init_next_conflictset()) { printf ("ERROR: creating new conflictset structure failed.\n"); exit(EXIT_FAILURE); } walk_policy(cur_node->children, doc, state | (1 << code)); break; case XML2BIN_TYPE: if (register_type(cur_node, doc, state)) exit(EXIT_FAILURE); /* type leaf */ break; case XML2BIN_LABELTEMPLATE: /* handle in second pass */ case XML2BIN_TEXT: case XML2BIN_COMMENT: case XML2BIN_DATE: case XML2BIN_REFERENCE: case XM
// dear imgui: Platform Binding for Windows (standard windows API for 32 and 64 bits applications)
// This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..)

// Implemented features:
//  [X] Platform: Clipboard support (for Win32 this is actually part of core imgui)
//  [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
//  [X] Platform: Keyboard arrays indexed using VK_* Virtual Key Codes, e.g. ImGui::IsKeyPressed(VK_SPACE).
// Missing features:
//  [ ] Platform: Gamepad support (best leaving it to user application to fill io.NavInputs[] with gamepad inputs from their source of choice).

#include "imgui.h"
#include "imgui_impl_win32.h"
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#include <tchar.h>

// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
//  2018-06-29: Inputs: Added support for the ImGuiMouseCursor_Hand cursor.
//  2018-06-10: Inputs: Fixed handling of mouse wheel messages to support fine position messages (typically sent by track-pads).
//  2018-06-08: Misc: Extracted imgui_impl_win32.cpp/.h away from the old combined DX9/DX10/DX11/DX12 examples.
//  2018-03-20: Misc: Setup io.BackendFlags ImGuiBackendFlags_HasMouseCursors and ImGuiBackendFlags_HasSetMousePos flags + honor ImGuiConfigFlags_NoMouseCursorChange flag.
//  2018-02-20: Inputs: Added support for mouse cursors (ImGui::GetMouseCursor() value and WM_SETCURSOR message handling).
//  2018-02-06: Inputs: Added mapping for ImGuiKey_Space.
//  2018-02-06: Inputs: Honoring the io.WantSetMousePos by repositioning the mouse (when using navigation and ImGuiConfigFlags_NavMoveMouse is set).
//  2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves.
//  2018-01-20: Inputs: Added Horizontal Mouse Wheel support.
//  2018-01-08: Inputs: Added mapping for ImGuiKey_Insert.
//  2018-01-05: Inputs: Added WM_LBUTTONDBLCLK double-click handlers for window classes with the CS_DBLCLKS flag.
//  2017-10-23: Inputs: Added WM_SYSKEYDOWN / WM_SYSKEYUP handlers so e.g. the VK_MENU key can be read.
//  2017-10-23: Inputs: Using Win32 ::SetCapture/::GetCapture() to retrieve mouse positions outside the client area when dragging. 
//  2016-11-12: Inputs: Only call Win32 ::SetCursor(NULL) when io.MouseDrawCursor is set.

// Win32 Data
static HWND                 g_hWnd = 0;
static INT64                g_Time = 0;
static INT64                g_TicksPerSecond = 0;
static ImGuiMouseCursor     g_LastMouseCursor = ImGuiMouseCursor_COUNT;

// Functions
bool    ImGui_ImplWin32_Init(void* hwnd)
{
    if (!::QueryPerformanceFrequency((LARGE_INTEGER *)&g_TicksPerSecond))
        return false;
    if (!::QueryPerformanceCounter((LARGE_INTEGER *)&g_Time))
        return false;

    // Setup back-end capabilities flags
    g_hWnd = (HWND)hwnd;
    ImGuiIO& io = ImGui::GetIO();
    io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors;         // We can honor GetMouseCursor() values (optional)
    io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos;          // We can honor io.WantSetMousePos requests (optional, rarely used)
    io.ImeWindowHandle = hwnd;

    // Keyboard mapping. ImGui will use those indices to peek into the io.KeysDown[] array that we will update during the application lifetime.
    io.KeyMap[ImGuiKey_Tab] = VK_TAB;
    io.KeyMap[ImGuiKey_LeftArrow] = VK_LEFT;
    io.KeyMap[ImGuiKey_RightArrow] = VK_RIGHT;
    io.KeyMap[ImGuiKey_UpArrow] = VK_UP;
    io.KeyMap[ImGuiKey_DownArrow] = VK_DOWN;
    io.KeyMap[ImGuiKey_PageUp] = VK_PRIOR;
    io.KeyMap[ImGuiKey_PageDown] = VK_NEXT;
    io.KeyMap[ImGuiKey_Home] = VK_HOME;
    io.KeyMap[ImGuiKey_End] = VK_END;
    io.KeyMap[ImGuiKey_Insert] = VK_INSERT;
    io.KeyMap[ImGuiKey_Delete] = VK_DELETE;
    io.KeyMap[ImGuiKey_Backspace] = VK_BACK;
    io.KeyMap[ImGuiKey_Space] = VK_SPACE;
    io.KeyMap[ImGuiKey_Enter] = VK_RETURN;
    io.KeyMap[ImGuiKey_Escape] = VK_ESCAPE;
    io.KeyMap[ImGuiKey_A] = 'A';
    io.KeyMap[ImGuiKey_C] = 'C';
    io.KeyMap[ImGuiKey_V] = 'V';
    io.KeyMap[ImGuiKey_X] = 'X';
    io.KeyMap[ImGuiKey_Y] = 'Y';
    io.KeyMap[ImGuiKey_Z] = 'Z';

    return true;
}

void    ImGui_ImplWin32_Shutdown()
{
    g_hWnd = (HWND)0;
}

static bool ImGui_ImplWin32_UpdateMouseCursor()
{
    ImGuiIO& io = ImGui::GetIO();
    if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange)
        return false;

    ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor();
    if (imgui_cursor == ImGuiMouseCursor_None || io.MouseDrawCursor)
    {
        // Hide OS mouse cursor if imgui is drawing it or if it wants no cursor
        ::SetCursor(NULL);
    }
    else
    {
        // Show OS mouse cursor
        LPTSTR win32_cursor = IDC_ARROW;
        switch (imgui_cursor)
        {
        case ImGuiMouseCursor_Arrow:        win32_cursor = IDC_ARROW; break;
        case ImGuiMouseCursor_TextInput:    win32_cursor = IDC_IBEAM; break;
        case ImGuiMouseCursor_ResizeAll:    win32_cursor = IDC_SIZEALL; break;
        case ImGuiMouseCursor_ResizeEW:     win32_cursor = IDC_SIZEWE; break;
        case ImGuiMouseCursor_ResizeNS:     win32_cursor = IDC_SIZENS; break;
        case ImGuiMouseCursor_ResizeNESW:   win32_cursor = IDC_SIZENESW; break;
        case ImGuiMouseCursor_ResizeNWSE:   win32_cursor = IDC_SIZENWSE; break;
        case ImGuiMouseCursor_Hand:         win32_cursor = IDC_HAND; break;
        }
        ::SetCursor(::LoadCursor(NULL, win32_cursor));
    }
    return true;
}

static void ImGui_ImplWin32_UpdateMousePos()
{
    ImGuiIO& io = ImGui::GetIO();

    // Set OS mouse position if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
    if (io.WantSetMousePos)
    {
        POINT pos = { (int)io.MousePos.x, (int)io.MousePos.y };
        ::ClientToScreen(g_hWnd, &pos);
        ::SetCursorPos(pos.x, pos.y);
    }

    // Set mouse position
    io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX);
    POINT pos;
    if (::GetActiveWindow() == g_hWnd && ::GetCursorPos(&pos))
        if (::ScreenToClient(g_hWnd, &pos))
            io.MousePos = ImVec2((float)pos.x, (float)pos.y);
}

void    ImGui_ImplWin32_NewFrame()
{
    ImGuiIO& io = ImGui::GetIO();

    // Setup display size (every frame to accommodate for window resizing)
    RECT rect;
    ::GetClientRect(g_hWnd, &rect);
    io.DisplaySize = ImVec2((float)(rect.right - rect.left), (float)(rect.bottom - rect.top));

    // Setup time step
    INT64 current_time;
    ::QueryPerformanceCounter((LARGE_INTEGER *)&current_time);
    io.DeltaTime = (float)(current_time - g_Time) / g_TicksPerSecond;
    g_Time = current_time;

    // Read keyboard modifiers inputs
    io.KeyCtrl = (::GetKeyState(VK_CONTROL) & 0x8000) != 0;
    io.KeyShift = (::GetKeyState(VK_SHIFT) & 0x8000) != 0;
    io.KeyAlt = (::GetKeyState(VK_MENU) & 0x8000) != 0;
    io.KeySuper = false;
    // io.KeysDown[], io.MousePos, io.MouseDown[], io.MouseWheel: filled by the WndProc handler below.

    // Update OS mouse position
    ImGui_ImplWin32_UpdateMousePos();

    // Update OS mouse cursor with the cursor requested by imgui
    ImGuiMouseCursor mouse_cursor = io.MouseDrawCursor ? ImGuiMouseCursor_None : ImGui::GetMouseCursor();
    if (g_LastMouseCursor != mouse_cursor)
    {
        g_LastMouseCursor = mouse_cursor;
        ImGui_ImplWin32_UpdateMouseCursor();
    }
}

// Allow compilation with old Windows SDK. MinGW doesn't have default _WIN32_WINNT/WINVER versions.
#ifndef WM_MOUSEHWHEEL
#define WM_MOUSEHWHEEL 0x020E
#endif

// Process Win32 mouse/keyboard inputs. 
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application.
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application.
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
// PS: In this Win32 handler, we use the capture API (GetCapture/SetCapture/ReleaseCapture) to be able to read mouse coordinations when dragging mouse outside of our window bounds.
// PS: We treat DBLCLK messages as regular mouse down messages, so this code will work on windows classes that have the CS_DBLCLKS flag set. Our own example app code doesn't set this flag.
IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    if (ImGui::GetCurrentContext() == NULL)
        return 0;

    ImGuiIO& io = ImGui::GetIO();
    switch (msg)
    {
    case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK:
    case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK:
    case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK:
    {
        int button = 0;
        if (msg == WM_LBUTTONDOWN || msg == WM_LBUTTONDBLCLK) button = 0;
        if (msg == WM_RBUTTONDOWN || msg == WM_RBUTTONDBLCLK) button = 1;
        if (msg == WM_MBUTTONDOWN || msg == WM_MBUTTONDBLCLK) button = 2;
        if (!ImGui::IsAnyMouseDown() && ::GetCapture() == NULL)
            ::SetCapture(hwnd);
        io.MouseDown[button] = true;
        return 0;
    }
    case WM_LBUTTONUP:
    case WM_RBUTTONUP:
    case WM_MBUTTONUP:
    {
        int button = 0;
        if (msg == WM_LBUTTONUP) button = 0;
        if (msg == WM_RBUTTONUP) button = 1;
        if (msg == WM_MBUTTONUP) button = 2;
        io.MouseDown[button] = false;
        if (!ImGui::IsAnyMouseDown() && ::GetCapture() == hwnd)
            ::ReleaseCapture();
        return 0;
    }
    case WM_MOUSEWHEEL:
        io.MouseWheel += (float)GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA;
        return 0;
    case WM_MOUSEHWHEEL:
        io.MouseWheelH += (float)GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA;
        return 0;
    case WM_KEYDOWN:
    case WM_SYSKEYDOWN:
        if (wParam < 256)
            io.KeysDown[wParam] = 1;
        return 0;
    case WM_KEYUP:
    case WM_SYSKEYUP:
        if (wParam < 256)
            io.KeysDown[wParam] = 0;
        return 0;
    case WM_CHAR:
        // You can also use ToAscii()+GetKeyboardState() to retrieve characters.
        if (wParam > 0 && wParam < 0x10000)
            io.AddInputCharacter((unsigned short)wParam);
        return 0;
    case WM_SETCURSOR:
        if (LOWORD(lParam) == HTCLIENT && ImGui_ImplWin32_UpdateMouseCursor())
            return 1;
        return 0;
    }
    return 0;
}