{-# LANGUAGE CPP #-} #if __GLASGOW_HASKELL__ >= 702 {-# LANGUAGE Trustworthy #-} #endif {-| This module provides bindings for the @DCLabel@ module, with some renaming to resolve name clashes. The delegation of privilege and other trusted code is not exported by this module and code wishing to use this should import @DCLabel.TCB@. -} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE TypeSynonymInstances #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE DeriveDataTypeable #-} module LIO.DCLabel ( -- * DCLabel export module DCLabel.Safe , DCCatSet -- * Renamed privileges , DCPriv, DCPrivTCB -- * Useful aliases for the LIO Monad , DCLabeled, DC, evalDC, evalDCWithRoot )where import LIO.TCB import LIO.Handle (evalWithRoot) #if __GLASGOW_HASKELL__ >= 702 import safe Data.Typeable #else import Data.Typeable #endif import DCLabel.Safe hiding ( Priv , bottom , top , join , meet) import qualified DCLabel.Core as DCL deriving instance Typeable DCL.Disj deriving instance Typeable DCL.Conj deriving instance Typeable DCL.Component deriving instance Typeable DCL.DCLabel instance Label DCLabel where lbot = DCL.bottom ltop = DCL.top lub = DCL.join glb = DCL.meet leq = DCL.canflowto instance PrivTCB DCL.TCBPriv instance MintTCB DCL.TCBPriv DCL.Priv where mintTCB = DCL.createPrivTCB instance MintTCB DCL.TCBPriv DCL.Principal where mintTCB p = DCL.createPrivTCB (newPriv p) instance Priv DCLabel DCL.TCBPriv where leqp = DCL.canflowto_p {- The implementation of lostar deserves an explanation. Firstly note that the properties, for @r = lostar p l g@ that must be satisfied are [the suffix \'s\' (\'i\')is used for seecrecy (resp. integrity): 1.) @leq g r : (rs => gs) and (gi => ri)@ 2.) @leqp p l r : (rs /\ p => ls) and (li /\ p => ri)@ Finding the integrity component of @r@ is trivial: it's simply the least upper bound of @gi@ and @li /\ p@. Finding the secrecy component is a bit trickier. To do so, we first find all the categories of @ls@ that are not implied by @p@ (this gives us @rs'@), such that @rs' /\ p => ls@. Then, we need to find the remaining categories in @gs@ that are not implied by @rs'@ (this gives us @rs''@). Directly, @rs = rs' /\ rs''@. -} lostar p l g = let (ls, li) = (DCL.toLNF . secrecy $ l, DCL.toLNF . integrity $ l) (gs, gi) = (DCL.toLNF . secrecy $ g, DCL.toLNF . integrity $ g) lp = DCL.toLNF . DCL.priv $ p rs' = c2l [c | c <- getCats ls , not (lp `DCL.implies` (c2l [c]))] rs'' = c2l [c | c <- getCats gs , not (rs' `DCL.implies` (c2l [c]))] rs = rs' `DCL.and_component` rs'' ri = (li `DCL.and_component` lp) `DCL.or_component` gi in DCL.toLNF $ simpleNewLabel p (newDC rs ri) where getCats = DCL.conj . DCL.component c2l = DCL.MkComponent . DCL.MkConj simpleNewLabel pr lr | pr == DCL.rootPrivTCB = g | pr == DCL.noPriv = l `lub` g | otherwise = lr -- -- Renaming -- -- | A @DCLabel@ category set. type DCCatSet = DCL.Component -- | A @DCLabel@ (untrusted) privilege. type DCPriv = DCL.Priv -- | A @DCLabel@ privilege. type DCPrivTCB = DCL.TCBPriv -- -- LIO aliases -- instance LabelState DCLabel DCPrivTCB () where -- | The type for 'Labeled' values uinsg 'DCLabel' as the label. type DCLabeled a = Labeled DCLabel a -- | The monad for LIO computations using 'DCLabel' as the label. type DC = LIO DCLabel DCPrivTCB () -- | Runs a computation in the LIO Monad, returning both the -- computation's result and the label of the result. evalDC :: DC a -> IO (a, DCLabel) evalDC m = evalLIO m () -- | Same as 'evalDC', but with support for filesystem. evalDCWithRoot :: FilePath -> Maybe DCLabel -> DC a -> IO (a, DCLabel) evalDCWithRoot path ml act = evalWithRoot path ml act ()