Safe Haskell | Trustworthy |
---|
This module abstracts the basic FileHandle
methods provided by
the system library, and provides an LHandle
(Labeled
Handle
)
type that can be manipulated from within the LIO
Monad.
(There is no notion of changeable current working directory in
the LIO
Monad, nor symbolic links.)
The actual storage of labeled files is handled by the LIO.FS module.
IMPORTANT: To use a labeled filesystem you must use evalWithRoot
,
otherwise any actions built using the combinators of this module will
crash.
An example use is shown below:
main = dcEvalWithRoot "/tmp/lioFS" $ do createDirectoryP p lsecrets "secrets" writeFileP p ("secrets" </> "alice" ) "I like Bob!" where p = ... lsecrets = ....
The file store for the labeled filesystem (see LIO.FS) will
be created in /tmp/lioFS
, but this is transparent and the user
can think of the filesystem as having root /
.
- evalWithRoot :: (Serialize l, LabelState l p s) => FilePath -> Maybe l -> LIO l p s a -> s -> IO (a, l)
- class Monad m => DirectoryOps h m | m -> h where
- getDirectoryContents :: FilePath -> m [FilePath]
- createDirectory :: FilePath -> m ()
- openFile :: FilePath -> IOMode -> m h
- class Monad m => CloseOps h m where
- class CloseOps h m => HandleOps h b m where
- readFile :: (DirectoryOps h m, HandleOps h b m) => FilePath -> m b
- writeFile :: (DirectoryOps h m, HandleOps h b m, OnExceptionTCB m) => FilePath -> b -> m ()
- writeFileL :: (HandleOps Handle b IO, LabelState l p s, Serialize l) => l -> FilePath -> b -> LIO l p s ()
- data IOMode
- = ReadMode
- | WriteMode
- | AppendMode
- | ReadWriteMode
- data LHandle l
- labelOfHandle :: Label l => LHandle l -> l
- getDirectoryContentsP :: (LabelState l p s, Serialize l) => p -> FilePath -> LIO l p s [FilePath]
- createDirectoryP :: (LabelState l p s, Serialize l) => p -> l -> FilePath -> LIO l p s ()
- openFileP :: (LabelState l p s, Serialize l) => p -> Maybe l -> FilePath -> IOMode -> LIO l p s (LHandle l)
- hCloseP :: LabelState l p s => p -> LHandle l -> LIO l p s ()
- hFlushP :: LabelState l p s => p -> LHandle l -> LIO l p s ()
- hGetP :: (LabelState l p s, HandleOps Handle b IO) => p -> LHandle l -> Int -> LIO l p s b
- hGetNonBlockingP :: (LabelState l p s, HandleOps Handle b IO) => p -> LHandle l -> Int -> LIO l p s b
- hGetContentsP :: (LabelState l p s, HandleOps Handle b IO) => p -> LHandle l -> LIO l p s b
- hPutP :: (LabelState l p s, HandleOps Handle b IO) => p -> LHandle l -> b -> LIO l p s ()
- hPutStrP :: (LabelState l p s, HandleOps Handle b IO) => p -> LHandle l -> b -> LIO l p s ()
- hPutStrLnP :: (LabelState l p s, HandleOps Handle b IO) => p -> LHandle l -> b -> LIO l p s ()
- readFileP :: (HandleOps Handle b IO, LabelState l p s, Serialize l) => p -> FilePath -> LIO l p s b
- writeFileP :: (HandleOps Handle b IO, LabelState l p s, Serialize l) => p -> FilePath -> b -> LIO l p s ()
- writeFileLP :: (HandleOps Handle b IO, LabelState l p s, Serialize l) => p -> l -> FilePath -> b -> LIO l p s ()
LIO with filesystem support
:: (Serialize l, LabelState l p s) | |
=> FilePath | Filesystem root |
-> Maybe l | Label of root |
-> LIO l p s a | LIO action |
-> s | Initial state |
-> IO (a, l) |
Same as evalLIO
, but takes two additional parameters
corresponding to the path of the labeled filesystem store and the
label of the root. If the labeled filesystem store does not exist,
it is created at the specified path with the root having the
supplied label.
If the filesystem does exist, the supplied label is ignored and thus
unnecessary. However, if the root label is not provided and the
filesystem has not been initialized, then lbot
is used as the
root label.
Generic Handle operations
class Monad m => DirectoryOps h m | m -> h whereSource
Class used to abstract reading and creating directories, and opening (possibly creating) files.
getDirectoryContents :: FilePath -> m [FilePath]Source
Get the contents of a directory.
createDirectory :: FilePath -> m ()Source
Create a directory at the supplied path. The LIO instance labels the directory with the current label.
openFile :: FilePath -> IOMode -> m hSource
Open handle to manage the file at the supplied path.
DirectoryOps Handle IO | |
(Serialize l, LabelState l p s) => DirectoryOps (LHandle l) (LIO l p s) |
class Monad m => CloseOps h m whereSource
Class used to abstract close and flush operations on handles.
class CloseOps h m => HandleOps h b m whereSource
Class used to abstract reading and writing from and to handles, respectively.
hGetNonBlocking :: h -> Int -> m bSource
hGetContents :: h -> m bSource
readFile :: (DirectoryOps h m, HandleOps h b m) => FilePath -> m bSource
Reads a file and returns the contents of the file as a (Byte)String.
writeFile :: (DirectoryOps h m, HandleOps h b m, OnExceptionTCB m) => FilePath -> b -> m ()Source
Write a (Byte)String to a file.
writeFileL :: (HandleOps Handle b IO, LabelState l p s, Serialize l) => l -> FilePath -> b -> LIO l p s ()Source
Same as writeFile
but also takes the label of the file.
LIO Handle
A labeled handle.
(LabelState l p s, CloseOps (LHandle l) (LIO l p s), HandleOps Handle b IO) => HandleOps (LHandle l) b (LIO l p s) | |
LabelState l p s => CloseOps (LHandle l) (LIO l p s) | |
(Serialize l, LabelState l p s) => DirectoryOps (LHandle l) (LIO l p s) |
labelOfHandle :: Label l => LHandle l -> lSource
Get the label of a labeled handle.
Privileged combinators
:: (LabelState l p s, Serialize l) | |
=> p | Privilege |
-> FilePath | Directory |
-> LIO l p s [FilePath] |
Get the contents of a directory. The current label is raised to
the join of the current label and that of all the directories
traversed to the leaf directory (of course, using privileges to
keep the current label unchanged when possible). Note that, unlike
the standard Haskell getDirectoryContents
, we first normalise the
path by collapsing all the ..
's. (The LIO filesystem does not
support links.)
:: (LabelState l p s, Serialize l) | |
=> p | Privilege |
-> l | Label of new directory |
-> FilePath | Path of directory |
-> LIO l p s () |
Create a directory at the supplied path with the given label. The current label (after traversing the filesystem to the directory path) must flow to the supplied label which in turn must flow to the current label (of course, using privileges to bypass certain restrictions). If this information flow restriction is satisfied, the directory is created.
:: (LabelState l p s, Serialize l) | |
=> p | Privileges |
-> Maybe l | Label of file if created |
-> FilePath | File to open |
-> IOMode | Mode of handle |
-> LIO l p s (LHandle l) |
Given a set of privileges, a new (maybe) label of a file, a filepath and the handle mode, open (and possibly create) the file. If the file exists the supplied label is not necessary; otherwise it must be supplied. The current label is raised to reflect all the traversed directories (of course, using privileges to minimize the taint). Additionally the label of the file (new or existing) must be between the current label and clearance. If the file is created, it is further required that the current process be able to write to the containing directory.
:: (LabelState l p s, HandleOps Handle b IO) | |
=> p | Privileges |
-> LHandle l | Labeled handle |
-> Int | Number of bytes to read |
-> LIO l p s b |
Read n
bytes from the labeled handle, using privileges when
performing label comparisons and tainting.
hGetNonBlockingP :: (LabelState l p s, HandleOps Handle b IO) => p -> LHandle l -> Int -> LIO l p s bSource
Same as hGetP
, but will not block waiting for data to become
available. Instead, it returns whatever data is available.
Privileges are used in the label comparisons and when raising
the current label.
hGetContentsP :: (LabelState l p s, HandleOps Handle b IO) => p -> LHandle l -> LIO l p s bSource
Read the entire labeled handle contents and close handle upon
reading EOF
. Privileges are used in the label comparisons
and when raising the current label.
hPutP :: (LabelState l p s, HandleOps Handle b IO) => p -> LHandle l -> b -> LIO l p s ()Source
Output the given (Byte)String to the specified labeled handle. Privileges are used in the label comparisons and when raising the current label.
hPutStrP :: (LabelState l p s, HandleOps Handle b IO) => p -> LHandle l -> b -> LIO l p s ()Source
Synonym for hPutP
.
hPutStrLnP :: (LabelState l p s, HandleOps Handle b IO) => p -> LHandle l -> b -> LIO l p s ()Source
Output the given (Byte)String with an appended newline to the specified labeled handle. Privileges are used in the label comparisons and when raising the current label.
readFileP :: (HandleOps Handle b IO, LabelState l p s, Serialize l) => p -> FilePath -> LIO l p s bSource
Same as readFile
but uses privilege in opening the file.
writeFileP :: (HandleOps Handle b IO, LabelState l p s, Serialize l) => p -> FilePath -> b -> LIO l p s ()Source
Same as writeFile
but uses privilege in opening the file.
writeFileLP :: (HandleOps Handle b IO, LabelState l p s, Serialize l) => p -> l -> FilePath -> b -> LIO l p s ()Source
Same as writeFileL
but uses privilege in opening the file.