packages feed

bindings-sipc (empty) → 1.0

raw patch · 9 files changed

+545/−0 lines, 9 filesdep +basedep +bindings-sipcsetup-changed

Dependencies added: base, bindings-sipc

Files

+ LICENSE view
@@ -0,0 +1,165 @@+                   GNU LESSER GENERAL PUBLIC LICENSE+                       Version 3, 29 June 2007++ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>+ Everyone is permitted to copy and distribute verbatim copies+ of this license document, but changing it is not allowed.+++  This version of the GNU Lesser General Public License incorporates+the terms and conditions of version 3 of the GNU General Public+License, supplemented by the additional permissions listed below.++  0. Additional Definitions.++  As used herein, "this License" refers to version 3 of the GNU Lesser+General Public License, and the "GNU GPL" refers to version 3 of the GNU+General Public License.++  "The Library" refers to a covered work governed by this License,+other than an Application or a Combined Work as defined below.++  An "Application" is any work that makes use of an interface provided+by the Library, but which is not otherwise based on the Library.+Defining a subclass of a class defined by the Library is deemed a mode+of using an interface provided by the Library.++  A "Combined Work" is a work produced by combining or linking an+Application with the Library.  The particular version of the Library+with which the Combined Work was made is also called the "Linked+Version".++  The "Minimal Corresponding Source" for a Combined Work means the+Corresponding Source for the Combined Work, excluding any source code+for portions of the Combined Work that, considered in isolation, are+based on the Application, and not on the Linked Version.++  The "Corresponding Application Code" for a Combined Work means the+object code and/or source code for the Application, including any data+and utility programs needed for reproducing the Combined Work from the+Application, but excluding the System Libraries of the Combined Work.++  1. Exception to Section 3 of the GNU GPL.++  You may convey a covered work under sections 3 and 4 of this License+without being bound by section 3 of the GNU GPL.++  2. Conveying Modified Versions.++  If you modify a copy of the Library, and, in your modifications, a+facility refers to a function or data to be supplied by an Application+that uses the facility (other than as an argument passed when the+facility is invoked), then you may convey a copy of the modified+version:++   a) under this License, provided that you make a good faith effort to+   ensure that, in the event an Application does not supply the+   function or data, the facility still operates, and performs+   whatever part of its purpose remains meaningful, or++   b) under the GNU GPL, with none of the additional permissions of+   this License applicable to that copy.++  3. Object Code Incorporating Material from Library Header Files.++  The object code form of an Application may incorporate material from+a header file that is part of the Library.  You may convey such object+code under terms of your choice, provided that, if the incorporated+material is not limited to numerical parameters, data structure+layouts and accessors, or small macros, inline functions and templates+(ten or fewer lines in length), you do both of the following:++   a) Give prominent notice with each copy of the object code that the+   Library is used in it and that the Library and its use are+   covered by this License.++   b) Accompany the object code with a copy of the GNU GPL and this license+   document.++  4. Combined Works.++  You may convey a Combined Work under terms of your choice that,+taken together, effectively do not restrict modification of the+portions of the Library contained in the Combined Work and reverse+engineering for debugging such modifications, if you also do each of+the following:++   a) Give prominent notice with each copy of the Combined Work that+   the Library is used in it and that the Library and its use are+   covered by this License.++   b) Accompany the Combined Work with a copy of the GNU GPL and this license+   document.++   c) For a Combined Work that displays copyright notices during+   execution, include the copyright notice for the Library among+   these notices, as well as a reference directing the user to the+   copies of the GNU GPL and this license document.++   d) Do one of the following:++       0) Convey the Minimal Corresponding Source under the terms of this+       License, and the Corresponding Application Code in a form+       suitable for, and under terms that permit, the user to+       recombine or relink the Application with a modified version of+       the Linked Version to produce a modified Combined Work, in the+       manner specified by section 6 of the GNU GPL for conveying+       Corresponding Source.++       1) Use a suitable shared library mechanism for linking with the+       Library.  A suitable mechanism is one that (a) uses at run time+       a copy of the Library already present on the user's computer+       system, and (b) will operate properly with a modified version+       of the Library that is interface-compatible with the Linked+       Version.++   e) Provide Installation Information, but only if you would otherwise+   be required to provide such information under section 6 of the+   GNU GPL, and only to the extent that such information is+   necessary to install and execute a modified version of the+   Combined Work produced by recombining or relinking the+   Application with a modified version of the Linked Version. (If+   you use option 4d0, the Installation Information must accompany+   the Minimal Corresponding Source and Corresponding Application+   Code. If you use option 4d1, you must provide the Installation+   Information in the manner specified by section 6 of the GNU GPL+   for conveying Corresponding Source.)++  5. Combined Libraries.++  You may place library facilities that are a work based on the+Library side by side in a single library together with other library+facilities that are not Applications and are not covered by this+License, and convey such a combined library under terms of your+choice, if you do both of the following:++   a) Accompany the combined library with a copy of the same work based+   on the Library, uncombined with any other library facilities,+   conveyed under the terms of this License.++   b) Give prominent notice with the combined library that part of it+   is a work based on the Library, and explaining where to find the+   accompanying uncombined form of the same work.++  6. Revised Versions of the GNU Lesser General Public License.++  The Free Software Foundation may publish revised and/or new versions+of the GNU Lesser General Public License from time to time. Such new+versions will be similar in spirit to the present version, but may+differ in detail to address new problems or concerns.++  Each version is given a distinguishing version number. If the+Library as you received it specifies that a certain numbered version+of the GNU Lesser General Public License "or any later version"+applies to it, you have the option of following the terms and+conditions either of that published version or of any later version+published by the Free Software Foundation. If the Library as you+received it does not specify a version number of the GNU Lesser+General Public License, you may choose any version of the GNU Lesser+General Public License ever published by the Free Software Foundation.++  If the Library as you received it specifies that a proxy can decide+whether future versions of the GNU Lesser General Public License shall+apply, that proxy's public statement of acceptance of any version is+permanent authorization for you to choose that version for the+Library.
+ README.markdown view
@@ -0,0 +1,22 @@+Haskell bindings for the [Secure Inter-Process Communications Library](http://oss.tresys.com/projects/sipc) for SELinux.++Installation+------------++The SIPC C library must be installed before the bindings. Please download it from [this page](http://oss.tresys.com/projects/sipc/wiki/download) and follow the installation instructions.++Once the library is available, Haskell bindings can be installed using `cabal`:++    cabal update+    cabal install bindings-sipc++Testing+-------++Example programs are provided to test message queues. Before using them you need to copy `data.txt` from the SIPC examples directory, and you need to create a file `sipc_mq_test`. The programs can then be executed in order:++    $ MQCreator+    $ MQReader &  # Either run in background or in another terminal+    $ MQSender+    $ MQDestroyer+
+ Setup.hs view
@@ -0,0 +1,3 @@+#!/usr/bin/env runhaskell+import Distribution.Simple+main = defaultMain
+ bindings-sipc.cabal view
@@ -0,0 +1,50 @@+Name:                bindings-sipc +Version:             1.0 +Synopsis:            Low level bindings to SIPC. +Description:         Low level bindings for the SELinux Secure Inter-Process+                     Communications (SIPC) Library.+License:             LGPL+License-file:        LICENSE+Author:              Justin Ethier+Maintainer:          Justin Ethier <github.com/justinethier>+Homepage:            http://justinethier.github.com/hs-bindings-sipc+Cabal-Version:       >= 1.8+-- Build-Tools:         c2hs+Build-Type:          Simple+Category:            Security +Tested-with:         GHC == 7.0.4++Extra-Source-Files:  README.markdown+                     LICENSE+Source-Repository head+     Type:            git+     Location:        git://github.com/justinethier/hs-bindings-sipc.git++Library+  Build-Depends:   base >= 2.0 && < 5+--, c2hs+  Hs-Source-Dirs:  src+  Exposed-Modules: Bindings.SELinux.SIPC +  Extra-Libraries: sipc++-- Example/Test programs++Executable         MQCreator+  Build-Depends:   bindings-sipc, base >= 2.0 && < 5+  Main-is:         MQCreator.hs+  Hs-Source-Dirs:  src/Examples++Executable         MQDestroyer+  Build-Depends:   bindings-sipc, base >= 2.0 && < 5+  Main-is:         MQDestroyer.hs+  Hs-Source-Dirs:  src/Examples++Executable         MQReader+  Build-Depends:   bindings-sipc, base >= 2.0 && < 5+  Main-is:         MQReader.hs+  Hs-Source-Dirs:  src/Examples+ +Executable         MQSender+  Build-Depends:   bindings-sipc, base >= 2.0 && < 5+  Main-is:         MQSender.hs+  Hs-Source-Dirs:  src/Examples
+ src/Bindings/SELinux/SIPC.chs view
@@ -0,0 +1,138 @@+{- |+Module      : Bindings.SELinux.SIPC+Copyright   : Justin Ethier+License     : LGPL++Maintainer  : github.com/justinethier+Stability   : experimental+Portability : portable++This module provides Haskell bindings for the SELinux SIPC library.++-}++{-# LANGUAGE ForeignFunctionInterface#-}++module Bindings.SELinux.SIPC+    ( SipcRole(..)+    , SipcType(..)+    , SipcIOCtl(..)+    , SipcPtr+    , sipcOpen+    , sipcClose+    , sipcUnlink+    , sipcIoctl+    , sipcSendData +    , sipcGetDataPtr+    , sipcRecvData+    , sipcShmRecvDone+    ) where++import Foreign+import Foreign.C++-- The sipc header must be installed on your system+-- in order to compile this module!!+#include <sipc/sipc.h>++#c+enum SipcRole {+ SipcCreator  = SIPC_CREATOR,+ SipcSender   = SIPC_SENDER,+ SipcReceiver = SIPC_RECEIVER+};+enum SipcType {+ SipcSysvShm     = SIPC_SYSV_SHM,+ SipcSysvMqueues = SIPC_SYSV_MQUEUES,+ SipcNumTypes    = SIPC_NUM_TYPES+};+enum SipcIOCtl {+ SipcBlock   = SIPC_BLOCK,+ SipcNoblock = SIPC_NOBLOCK+};+#endc++-- |SIPC Roles+{#enum SipcRole {} deriving (Eq, Show)#}+-- |SIPC Types+{#enum SipcType {} deriving (Eq, Show)#}+-- |SIPC behaviors, for sipc_ioctl()+{#enum SipcIOCtl {} deriving (Eq, Show)#}++-- |A pointer to the sipc struct type+type SipcPtr = Ptr ()++{-+/* sipc_open(char *key, int role, int ipc_type, size_t size)+ *	key		Unique key to identify IPC communication channel,+ *			must be the same for the sender and reciever.+ *	role		SIPC_CREATOR if this application is the IPC creator,+ *			SIPC_SENDER for the sender and SIPC_RECEIVER+ *			for the reciever+ *	ipc_type	Which IPC type used, must be the same for sender+ *			and reciever.+ *	size		Maximum message size to be transmitted.+ *+-}++-- |This function must be called before any other function to initialize+--  the sipc struct.  Caller must call sipcClose to free the memory.+{#fun unsafe sipc_open as ^ {+    `String',               -- ^ Unique key to identify the communication channel +    cFromEnum `SipcRole', +    cFromEnum `SipcType', +    fromIntegral `CSize' +  } -> `SipcPtr' id #}++-- |Free the sipc struct and its contents+{#fun unsafe sipc_close as ^ {id `SipcPtr'} -> `()' #}++-- |Called by a helper application to destroy an IPC resource.+{#fun unsafe sipc_unlink as ^ {`String', cFromEnum `SipcType'} -> `()' #}++-- |Modify the behavior of an open SIPC channel.  Returns 0 on success,+--  <0 on failure.+{#fun unsafe sipc_ioctl as ^ {id `SipcPtr', cFromEnum `SipcIOCtl'} -> `Int' #}++-- |Blocking call to send msglen bytes of data.+--  This can only be called if sender was specified when sipcOpen was called.+--  returns 0 on success, <0 on failure+{#fun unsafe sipc_send_data as ^ {id `SipcPtr', fromIntegral `CSize'} -> `Int' #}++-- |Returns a pointer to the data contained within the IPC resource+{#fun unsafe sipc_get_data_ptr as ^ {id `SipcPtr'} -> `Ptr CChar' id #}++-- |Call to receive data.  Data will be allocated and filled and len+--  will be set to the length.  Returns 0 on success, <0 on failure.+sipcRecvData :: SipcPtr -> IO (Int, Ptr CChar, CSize)+sipcRecvData a1 =+  let {a1' = id a1} in+  alloca $ \a2' ->+  alloca $ \a3' ->+  sipcRecvData'_ a1' a2' a3' >>= \res ->+  peek  a2'>>= \a2'' ->+  peek  a3'>>= \a3'' ->+  let {res' = fromIntegral res} in+  return (res', a2'', fromIntegral a3'')+foreign import ccall unsafe "Bindings/SELinux/SIPC.chs.h sipc_recv_data"+  sipcRecvData'_ :: ((Ptr ()) -> ((Ptr (Ptr CChar)) -> ((Ptr CUInt) -> (IO CInt))))++-- FUTURE: It would be nice to use the following directive to generate +--         sipcRecvData, but CSize maps to either CUInt (32-bit) or+--         CULong (64-bit) and I can only get this #fun to work by +--         hardcoding one of those types instead of CSize: +--{#fun unsafe sipc_recv_data as ^ {id `SipcPtr', alloca- `Ptr CChar' peek*, alloca- `CSize' peek*} -> `Int' #}++-- |Receiver calls this when it is done receiving a message in shared+--  memory.  There must be exactly one call to sipcShmRecvDone() for+--  every call to sipcRecvData(), if the sipc was created as shared+--  memory.+{#fun unsafe sipc_shm_recv_done as ^ {id `SipcPtr'} -> `Int' #}++-- |Convert a Haskell enumeration to C.+-- +--  This code is from C2HS, but it has been added+--  here since C2HS is deprecated.+cFromEnum :: (Enum e, Integral i) => e -> i+cFromEnum  = fromIntegral . fromEnum+
+ src/Examples/MQCreator.hs view
@@ -0,0 +1,18 @@+-- A program to test creating a message queue.+-- +-- Based on sipc code from: examples/mq_creator.c+--+module Main where++import Bindings.SELinux.SIPC+import Foreign.Ptr+import System.IO++main :: IO ()+main = do+  sipc <- sipcOpen "sipc_mq_test" SipcCreator SipcSysvMqueues 0+  if sipc == nullPtr+     then do+        hPutStrLn stderr "Error: Unable to create message queue"+     else do+        sipcClose sipc
+ src/Examples/MQDestroyer.hs view
@@ -0,0 +1,13 @@+-- A program to test destroying a message queue.+-- +-- Based on sipc code from: examples/mq_destroyer.c+--+module Main where++import Bindings.SELinux.SIPC+import Foreign.Ptr+import System.IO++main :: IO ()+main = do+  sipcUnlink "sipc_mq_test" SipcSysvMqueues 
+ src/Examples/MQReader.hs view
@@ -0,0 +1,45 @@+-- A program to test receiving messages on a message queue.+-- +-- Based on sipc code from: examples/mq_reader.c+--+module Main where++import Bindings.SELinux.SIPC+import Control.Monad (when)+import Foreign+import Foreign.C+import System.IO++-- Key which sender and receiver have agreed upon +sipcKey = "sipc_mq_test"++-- Amount of data to allocate inside the IPC handle+dataLen = 8192++-- End of message marker which sender and receiver have agreed upon+dataEnd = "0xDEADBEEF"  ++main :: IO ()+main = do+  sipc <- sipcOpen sipcKey SipcReceiver SipcSysvMqueues dataLen+  if sipc == nullPtr+     then do+        hPutStrLn stderr "Error: Unable to create message queue"+     else do+        recvMessages sipc+        sipcClose sipc++-- |Receive data from shared memory until the end of transmission+--  marker has been received.+recvMessages :: SipcPtr -> IO ()+recvMessages sipc = do+    (result, dataP, len) <- sipcRecvData sipc+    when (result == 0) $ recv dataP+ where+    recv dataP = do+        dataStr <- peekCString dataP+        free dataP+        when (dataStr /= dataEnd) $ recvNext dataStr+    recvNext msg = do+        putStr msg+        recvMessages sipc
+ src/Examples/MQSender.hs view
@@ -0,0 +1,91 @@+-- A program to test sending messages to a message queue.+-- +-- Based on sipc code from: examples/mq_sender.c+--+module Main where++import Bindings.SELinux.SIPC+import Control.Monad (when)+import Foreign+import Foreign.C+import Foreign.Ptr+import Foreign.Storable+import System.IO++-- Key which sender and receiver have agreed upon +sipcKey = "sipc_mq_test"++-- # of bytes we allocate for the IPC's internal buffer.+-- This should be >= the amount of data copied into the IPC +ipcLen = 8192++-- # of bytes to read from data file at a time+readLen = 4096++-- Amount of data to allocate inside the IPC handle+dataLen = 8192++-- End of message marker which sender and receiver have agreed upon+dataEnd = "0xDEADBEEF"  ++-- Data file+inFile = "data.txt"++main :: IO ()+main = do+  sipc <- sipcOpen "sipc_mq_test" SipcSender SipcSysvMqueues ipcLen +  if sipc == nullPtr+     then do+        hPutStrLn stderr "Error: Unable to create message queue"+        sipcClose sipc+     else do+        dataP <- sipcGetDataPtr sipc+        if dataP == nullPtr+           then do+              hPutStrLn stderr "Error: Unable to get data pointer"+              sipcClose sipc+           else do +              sendFileData sipc dataP+              sendEndXmit sipc dataP+              sipcClose sipc++-- |Read and enqueue file data+sendFileData :: SipcPtr -> Ptr CChar -> IO ()+sendFileData sipc dataP = do+  f <- openFile inFile ReadMode+  fData <- hGetContents f+  sendFileChunks sipc dataP fData+  hClose f++-- |Send all chunks of a file to the queue+sendFileChunks sipc dataP chunkList = do+  let (c, cs) = splitAt readLen chunkList+  clearBuffer dataP+  sendMessage sipc dataP c+  when (not $ null cs) $ sendFileChunks sipc dataP cs++-- |Send data to the message queue+sendMessage :: SipcPtr -> Ptr CChar -> String -> IO ()+sendMessage sipc dataP msg = do+    tmpP <- newArray $ map castCharToCChar msg+    _ <- copyBytes dataP tmpP $ length msg+    free tmpP+    result <- sipcSendData sipc ipcLen+    when (result < 0) $ putStrLn $ "Unable to send IPC message"++-- |Send end of transmission marker+sendEndXmit sipc dataP = do+    tmpP <- newCAString dataEnd+    _ <- copyBytes dataP tmpP $ 1 + length dataEnd+    free tmpP+    result <- sipcSendData sipc ipcLen+    when (result < 0) $ putStrLn $ "Unable to send IPC message"++-- FUTURE: just replace this with memcpy?+-- A quick-and-dirty bzero+clearBuffer dataP = do+    let buffer = take (fromIntegral ipcLen) $ repeat '\0'+    tmpP <- newArray $ map castCharToCChar buffer+    _ <- copyBytes dataP tmpP $ length buffer+    free tmpP+