selinux (empty) → 0.1
raw patch · 4 files changed
+341/−0 lines, 4 filesdep +basedep +unixsetup-changed
Dependencies added: base, unix
Files
- LICENSE +30/−0
- Setup.hs +2/−0
- selinux.cabal +26/−0
- src/System/Linux/SELinux.hs +283/−0
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c)2011, Luite Stegeman++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++ * Redistributions in binary form must reproduce the above+ copyright notice, this list of conditions and the following+ disclaimer in the documentation and/or other materials provided+ with the distribution.++ * Neither the name of Luite Stegeman nor the names of other+ contributors may be used to endorse or promote products derived+ from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ selinux.cabal view
@@ -0,0 +1,26 @@+Name: selinux+Version: 0.1+Synopsis: SELinux bindings+Description: Haskell bindings for the SELinux API+License: BSD3+License-file: LICENSE+Author: Luite Stegeman+Maintainer: stegeman@gmail.com+Category: System+Build-type: Simple+Homepage: https://github.com/luite/selinux+Cabal-version: >=1.8++Source-repository head+ type: git+ location: https://github.com/luite/selinux.git++Library+ hs-source-dirs: src+ Exposed-modules:+ System.Linux.SELinux+ extra-libraries: selinux+ Build-depends:+ base >= 4 && < 5,+ unix >= 2.4 && < 2.6+
+ src/System/Linux/SELinux.hs view
@@ -0,0 +1,283 @@+{- | +Module : System.Linux.SELinux +Copyright : Luite Stegeman +Licence : BSD3 + +Maintainer : stegeman@gmail.com +Stability : provisional +Portability : portable + +Haskell bindings for the SELinux API. +-} + +{-#LANGUAGE ForeignFunctionInterface #-} + +{- + incomplete bindings, feel free to extend +-} + +module System.Linux.SELinux ( + SecurityContext, + EnforceMode(..), + isSELinuxEnabled, + isSELinuxMLSEnabled, + getEnforceMode, + getEnforce, + getCon, getConRaw, setCon, setConRaw, + getPidCon, getPidConRaw, + getPrevCon, getPrevConRaw, + getExecCon, getExecConRaw, setExecCon, setExecConRaw, + getFsCreateCon, getFsCreateConRaw, setFsCreateCon, setFsCreateConRaw, + getKeyCreateCon, getKeyCreateConRaw, setKeyCreateCon, setKeyCreateConRaw, + getSockCreateCon, getSockCreateConRaw, setSockCreateCon, setSockCreateConRaw, + getFileCon, getFileConRaw, + lgetFileCon, lgetFileConRaw, + fgetFileCon, fgetFileConRaw, + setFileCon, setFileConRaw, + lsetFileCon, lsetFileConRaw, + fsetFileCon, fsetFileConRaw, + getPeerCon, getPeerConRaw, + getConfigPolicyRoot, getConfigBinaryPolicyPath, + getConfigFailsafeContextPath, getConfigRemovableContextPath, + getConfigDefaultContextPath, getConfigUserContextsPath, + getConfigFileContextPath, getConfigFileContextHomedirPath, + getConfigFileContextLocalPath, getConfigFileContextSubsPath, + getConfigHomedirContextPath, getConfigMediaContextPath, + getConfigVirtualDomainContextPath, getConfigVirtualImageContextPath, + getConfigXContextPath, getConfigSepgsqlContextPath, + getConfigContextsPath, getConfigSecurettyTypesPath, + getConfigBooleansPath, getConfigCustomizableTypesPath, + getConfigUsersPath, getConfigUsersconfPath, + getConfigTranslationsPath, getConfigColorsPath, + getConfigNetfilterContextPath, getConfigPath + ) where + +import Control.Monad +import Foreign.C.Types (CInt) +import Foreign.C.String (CString, withCString, peekCString) +import Foreign.C.Error (throwErrnoIfMinus1, throwErrnoIfMinus1_, throwErrno) +import Foreign.Marshal.Alloc (alloca) +import Foreign.Ptr (Ptr, nullPtr) +import Foreign.Storable (peek) +import System.Posix.Types (CPid) + + +type SecurityContext = String + +data EnforceMode = Enforcing + | Permissive + | Disabled deriving (Show, Ord, Eq) + +isSELinuxEnabled :: IO Bool +isSELinuxEnabled = fmap i2b $ throwErrnoIfMinus1 "isSELinuxEnabled" c_is_selinux_enabled + +isSELinuxMLSEnabled :: IO Bool +isSELinuxMLSEnabled = fmap i2b $ throwErrnoIfMinus1 "isSELinuxMLSEnabled" c_is_selinux_mls_enabled + +getEnforceMode :: IO EnforceMode +getEnforceMode = alloca $ \ptr -> do + r <- c_selinux_getenforcemode ptr + if r == -1 + then throwErrno "getEnforceMode" + else fmap convertEnforceMode (peek ptr) + where + convertEnforceMode 1 = Enforcing + convertEnforceMode 0 = Permissive + convertEnforceMode _ = Disabled + +getEnforce :: IO Bool +getEnforce = fmap i2b $ throwErrnoIfMinus1 "getEnforce" c_security_getenforce + +getCon = queryCon "getCon" c_getcon +getConRaw = queryCon "getConRaw" c_getcon_raw +setCon = withCon "setCon" c_setcon +setConRaw = withCon "setConRaw" c_setcon_raw +getPidCon pid = queryCon "getPidCon" (c_getpidcon pid) +getPidConRaw pid = queryCon "getPidConRaw" (c_getpidcon_raw pid) +getPrevCon = queryCon "getPrevCon" c_getprevcon +getPrevConRaw = queryCon "getPrevConRaw" c_getprevcon_raw + +getExecCon = queryConMaybe "getExecCon" c_getexeccon +getExecConRaw = queryConMaybe "getExecConRaw" c_getexeccon_raw +setExecCon = withConMaybe "setExecCon" c_setexeccon +setExecConRaw = withConMaybe "setExecConRaw" c_setexeccon_raw + +getFsCreateCon = queryConMaybe "getFsCreateCon" c_getfscreatecon +getFsCreateConRaw = queryConMaybe "getFsCreateConRaw" c_getfscreatecon_raw +setFsCreateCon = withConMaybe "setFsCreateCon" c_setfscreatecon +setFsCreateConRaw = withConMaybe "setFsCreateConRaw" c_setfscreatecon_raw + +getKeyCreateCon = queryConMaybe "getKeyCreateCon" c_getkeycreatecon +getKeyCreateConRaw = queryConMaybe "getKeyCreateConRaw" c_getkeycreatecon_raw +setKeyCreateCon = withConMaybe "setKeyCreateCon" c_setkeycreatecon +setKeyCreateConRaw = withConMaybe "setKeyCreateConRaw" c_setkeycreatecon_raw + +getSockCreateCon = queryConMaybe "getSockCreateCon" c_getsockcreatecon +getSockCreateConRaw = queryConMaybe "getSockCreateConRaw" c_getsockcreatecon_raw +setSockCreateCon = withConMaybe "setSockCreateCon" c_setsockcreatecon +setSockCreateConRaw = withConMaybe "setSockCreateConRaw" c_setsockcreatecon_raw + +getFileCon = queryPathCon "getFileCon" c_getfilecon +getFileConRaw = queryPathCon "getFileConRaw" c_getfilecon_raw +lgetFileCon = queryPathCon "lgetFileCon" c_lgetfilecon +lgetFileConRaw = queryPathCon "lgetFileConRw" c_lgetfilecon_raw +fgetFileCon fd = queryCon "fgetFileCon" (c_fgetfilecon fd) +fgetFileConRaw fd = queryCon "fgetFileConRaw" (c_fgetfilecon_raw fd) + +setFileCon = withPathCon "setFileCon" c_setfilecon +setFileConRaw = withPathCon "setFileConRaw" c_setfilecon_raw +lsetFileCon = withPathCon "lsetFileCon" c_lsetfilecon +lsetFileConRaw = withPathCon "lsetfileConRaw" c_lsetfilecon_raw +fsetFileCon fd = withCon "fsetFileCon" (c_fsetfilecon fd) +fsetFileConRaw fd = withCon "fsetFileConRaw" (c_fsetfilecon_raw fd) + +getPeerCon fd = queryCon "getPeerCon" (c_getpeercon fd) +getPeerConRaw fd = queryCon "getPeerConRaw" (c_getpeercon_raw fd) + +getConfigPolicyRoot = queryConfig c_selinux_policy_root +getConfigBinaryPolicyPath = queryConfig c_selinux_binary_policy_path +getConfigFailsafeContextPath = queryConfig c_selinux_failsafe_context_path +getConfigRemovableContextPath = queryConfig c_selinux_removable_context_path +getConfigDefaultContextPath = queryConfig c_selinux_default_context_path +getConfigUserContextsPath = queryConfig c_selinux_user_contexts_path +getConfigFileContextPath = queryConfig c_selinux_file_context_path +getConfigFileContextHomedirPath = queryConfig c_selinux_file_context_homedir_path +getConfigFileContextLocalPath = queryConfig c_selinux_file_context_local_path +getConfigFileContextSubsPath = queryConfig c_selinux_file_context_subs_path +getConfigHomedirContextPath = queryConfig c_selinux_homedir_context_path +getConfigMediaContextPath = queryConfig c_selinux_media_context_path +getConfigVirtualDomainContextPath = queryConfig c_selinux_virtual_domain_context_path +getConfigVirtualImageContextPath = queryConfig c_selinux_virtual_image_context_path +getConfigXContextPath = queryConfig c_selinux_x_context_path +getConfigSepgsqlContextPath = queryConfig c_selinux_sepgsql_context_path +getConfigContextsPath = queryConfig c_selinux_contexts_path +getConfigSecurettyTypesPath = queryConfig c_selinux_securetty_types_path +getConfigBooleansPath = queryConfig c_selinux_booleans_path +getConfigCustomizableTypesPath = queryConfig c_selinux_customizable_types_path +getConfigUsersPath = queryConfig c_selinux_users_path +getConfigUsersconfPath = queryConfig c_selinux_usersconf_path +getConfigTranslationsPath = queryConfig c_selinux_translations_path +getConfigColorsPath = queryConfig c_selinux_colors_path +getConfigNetfilterContextPath = queryConfig c_selinux_netfilter_context_path +getConfigPath = queryConfig c_selinux_path + +--------------------------------------------------------------------------- + +i2b :: CInt -> Bool +i2b 0 = False +i2b _ = True + +withCon :: String -> (CSecurityContext -> IO CInt) -> SecurityContext -> IO () +withCon e f c = withCString c $ \ctx -> throwErrnoIfMinus1_ e (f ctx) + +withConMaybe :: String -> (CSecurityContext -> IO CInt) -> Maybe SecurityContext -> IO () +withConMaybe e f (Just c) = withCon e f c +withConMaybe e f Nothing = throwErrnoIfMinus1_ e (f nullPtr) + +withPathCon :: String -> (CString -> CSecurityContext -> IO CInt) -> FilePath -> SecurityContext -> IO () +withPathCon e f p c = withCString p $ \cp -> withCon e (f cp) c + +queryPathCon :: String -> (CString -> Ptr CSecurityContext -> IO CInt) -> FilePath -> IO SecurityContext +queryPathCon e f p = withCString p $ \p' -> queryCon e (f p') + +queryCon :: String -> (Ptr CSecurityContext -> IO CInt) -> IO SecurityContext +queryCon e f = alloca $ \ptr -> do + r <- f ptr + if r == -1 + then throwErrno e + else peek ptr >>= \ptr' -> peekCString ptr' >>= \str -> c_freecon ptr' >> return str + +queryConMaybe :: String -> (Ptr CSecurityContext -> IO CInt) -> IO (Maybe SecurityContext) +queryConMaybe e f = alloca $ \ptr -> do + r <- f ptr + if r == -1 + then throwErrno e + else peek ptr >>= \ptr' -> + if ptr' == nullPtr + then return Nothing + else peekCString ptr' >>= \str -> c_freecon ptr' >> return (Just str) + +-- |A helper function for reading values from the selinux config file +queryConfig :: IO CString -> IO String +queryConfig f = f >>= peekCString >>= return + + +type CSecurityContext = CString +foreign import ccall unsafe "selinux/selinux.h is_selinux_enabled" c_is_selinux_enabled :: IO CInt +foreign import ccall unsafe "selinux/selinux.h is_selinux_mls_enabled" c_is_selinux_mls_enabled :: IO CInt +foreign import ccall unsafe "selinux/selinux.h selinux_getenforcemode" c_selinux_getenforcemode :: Ptr CInt -> IO CInt +foreign import ccall unsafe "selinux/selinux.h security_getenforce" c_security_getenforce :: IO CInt +foreign import ccall unsafe "selinux/selinux.h freecon" c_freecon :: CSecurityContext -> IO () + +foreign import ccall unsafe "selinux/selinux.h getcon" c_getcon :: Ptr CSecurityContext -> IO CInt +foreign import ccall unsafe "selinux/selinux.h getcon_raw" c_getcon_raw :: Ptr CSecurityContext -> IO CInt +foreign import ccall unsafe "selinux/selinux.h setcon" c_setcon :: CSecurityContext -> IO CInt +foreign import ccall unsafe "selinux/selinux.h setcon_raw" c_setcon_raw :: CSecurityContext -> IO CInt +foreign import ccall unsafe "selinux/selinux.h getpidcon" c_getpidcon :: CPid -> Ptr CSecurityContext -> IO CInt +foreign import ccall unsafe "selinux/selinux.h getpidcon_raw" c_getpidcon_raw :: CPid -> Ptr CSecurityContext -> IO CInt +foreign import ccall unsafe "selinux/selinux.h getprevcon" c_getprevcon :: Ptr CSecurityContext -> IO CInt +foreign import ccall unsafe "selinux/selinux.h getprevcon_raw" c_getprevcon_raw :: Ptr CSecurityContext -> IO CInt +foreign import ccall unsafe "selinux/selinux.h getexeccon" c_getexeccon :: Ptr CSecurityContext -> IO CInt +foreign import ccall unsafe "selinux/selinux.h getexeccon_raw" c_getexeccon_raw :: Ptr CSecurityContext -> IO CInt +foreign import ccall unsafe "selinux/selinux.h setexeccon" c_setexeccon :: CSecurityContext -> IO CInt +foreign import ccall unsafe "selinux/selinux.h setexeccon_raw" c_setexeccon_raw :: CSecurityContext -> IO CInt +foreign import ccall unsafe "selinux/selinux.h getfscreatecon" c_getfscreatecon :: Ptr CSecurityContext -> IO CInt +foreign import ccall unsafe "selinux/selinux.h getfscreatecon_raw" c_getfscreatecon_raw :: Ptr CSecurityContext -> IO CInt +foreign import ccall unsafe "selinux/selinux.h setfscreatecon" c_setfscreatecon :: CSecurityContext -> IO CInt +foreign import ccall unsafe "selinux/selinux.h setfscreatecon_raw" c_setfscreatecon_raw :: CSecurityContext -> IO CInt +foreign import ccall unsafe "selinux/selinux.h getkeycreatecon" c_getkeycreatecon :: Ptr CSecurityContext -> IO CInt +foreign import ccall unsafe "selinux/selinux.h getkeycreatecon_raw" c_getkeycreatecon_raw :: Ptr CSecurityContext -> IO CInt +foreign import ccall unsafe "selinux/selinux.h setkeycreatecon" c_setkeycreatecon :: CSecurityContext -> IO CInt +foreign import ccall unsafe "selinux/selinux.h setkeycreatecon_raw" c_setkeycreatecon_raw :: CSecurityContext -> IO CInt +foreign import ccall unsafe "selinux/selinux.h getsockcreatecon" c_getsockcreatecon :: Ptr CSecurityContext -> IO CInt +foreign import ccall unsafe "selinux/selinux.h getsockcreatecon_raw" c_getsockcreatecon_raw :: Ptr CSecurityContext -> IO CInt +foreign import ccall unsafe "selinux/selinux.h setsockcreatecon" c_setsockcreatecon :: CSecurityContext -> IO CInt +foreign import ccall unsafe "selinux/selinux.h setsockcreatecon_raw" c_setsockcreatecon_raw :: CSecurityContext -> IO CInt + +foreign import ccall unsafe "selinux/selinux.h getfilecon" c_getfilecon :: CString -> Ptr CSecurityContext -> IO CInt +foreign import ccall unsafe "selinux/selinux.h getfilecon_raw" c_getfilecon_raw :: CString -> Ptr CSecurityContext -> IO CInt +foreign import ccall unsafe "selinux/selinux.h lgetfilecon" c_lgetfilecon :: CString -> Ptr CSecurityContext -> IO CInt +foreign import ccall unsafe "selinux/selinux.h lgetfilecon_raw" c_lgetfilecon_raw :: CString -> Ptr CSecurityContext -> IO CInt +foreign import ccall unsafe "selinux/selinux.h fgetfilecon" c_fgetfilecon :: CInt -> Ptr CSecurityContext -> IO CInt +foreign import ccall unsafe "selinux/selinux.h fgetfilecon_raw" c_fgetfilecon_raw :: CInt -> Ptr CSecurityContext -> IO CInt + +foreign import ccall unsafe "selinux/selinux.h setfilecon" c_setfilecon :: CString -> CSecurityContext -> IO CInt +foreign import ccall unsafe "selinux/selinux.h setfilecon_raw" c_setfilecon_raw :: CString -> CSecurityContext -> IO CInt +foreign import ccall unsafe "selinux/selinux.h lsetfilecon" c_lsetfilecon :: CString -> CSecurityContext -> IO CInt +foreign import ccall unsafe "selinux/selinux.h lsetfilecon_raw" c_lsetfilecon_raw :: CString -> CSecurityContext -> IO CInt +foreign import ccall unsafe "selinux/selinux.h fsetfilecon" c_fsetfilecon :: CInt -> CSecurityContext -> IO CInt +foreign import ccall unsafe "selinux/selinux.h fsetfilecon_raw" c_fsetfilecon_raw :: CInt -> CSecurityContext -> IO CInt + +foreign import ccall unsafe "selinux/selinux.h getpeercon" c_getpeercon :: CInt -> Ptr CSecurityContext -> IO CInt +foreign import ccall unsafe "selinux/selinux.h getpeercon_raw" c_getpeercon_raw :: CInt -> Ptr CSecurityContext -> IO CInt + +foreign import ccall unsafe "selinux/selinux.h selinux_policy_root" c_selinux_policy_root :: IO CString + +-- These functions return the paths to specific files under the +-- policy root directory. +foreign import ccall unsafe "selinux/selinux.h selinux_binary_policy_path" c_selinux_binary_policy_path :: IO CString +foreign import ccall unsafe "selinux/selinux.h selinux_failsafe_context_path" c_selinux_failsafe_context_path :: IO CString +foreign import ccall unsafe "selinux/selinux.h selinux_removable_context_path" c_selinux_removable_context_path :: IO CString +foreign import ccall unsafe "selinux/selinux.h selinux_default_context_path" c_selinux_default_context_path :: IO CString +foreign import ccall unsafe "selinux/selinux.h selinux_user_contexts_path" c_selinux_user_contexts_path :: IO CString +foreign import ccall unsafe "selinux/selinux.h selinux_file_context_path" c_selinux_file_context_path :: IO CString +foreign import ccall unsafe "selinux/selinux.h selinux_file_context_homedir_path" c_selinux_file_context_homedir_path :: IO CString +foreign import ccall unsafe "selinux/selinux.h selinux_file_context_local_path" c_selinux_file_context_local_path :: IO CString +foreign import ccall unsafe "selinux/selinux.h selinux_file_context_subs_path" c_selinux_file_context_subs_path :: IO CString +foreign import ccall unsafe "selinux/selinux.h selinux_homedir_context_path" c_selinux_homedir_context_path :: IO CString +foreign import ccall unsafe "selinux/selinux.h selinux_media_context_path" c_selinux_media_context_path :: IO CString +foreign import ccall unsafe "selinux/selinux.h selinux_virtual_domain_context_path" c_selinux_virtual_domain_context_path :: IO CString +foreign import ccall unsafe "selinux/selinux.h selinux_virtual_image_context_path" c_selinux_virtual_image_context_path :: IO CString +foreign import ccall unsafe "selinux/selinux.h selinux_x_context_path" c_selinux_x_context_path :: IO CString +foreign import ccall unsafe "selinux/selinux.h selinux_sepgsql_context_path" c_selinux_sepgsql_context_path :: IO CString +foreign import ccall unsafe "selinux/selinux.h selinux_contexts_path" c_selinux_contexts_path :: IO CString +foreign import ccall unsafe "selinux/selinux.h selinux_securetty_types_path" c_selinux_securetty_types_path :: IO CString +foreign import ccall unsafe "selinux/selinux.h selinux_booleans_path" c_selinux_booleans_path :: IO CString +foreign import ccall unsafe "selinux/selinux.h selinux_customizable_types_path" c_selinux_customizable_types_path :: IO CString +foreign import ccall unsafe "selinux/selinux.h selinux_users_path" c_selinux_users_path :: IO CString +foreign import ccall unsafe "selinux/selinux.h selinux_usersconf_path" c_selinux_usersconf_path :: IO CString +foreign import ccall unsafe "selinux/selinux.h selinux_translations_path" c_selinux_translations_path :: IO CString +foreign import ccall unsafe "selinux/selinux.h selinux_colors_path" c_selinux_colors_path :: IO CString +foreign import ccall unsafe "selinux/selinux.h selinux_netfilter_context_path" c_selinux_netfilter_context_path :: IO CString +foreign import ccall unsafe "selinux/selinux.h selinux_path" c_selinux_path :: IO CString +