lio-0.1.3: Labeled IO Information Flow Control Library

Safe HaskellTrustworthy

LIO.Handle

Contents

Description

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 /.

Synopsis

LIO with filesystem support

evalWithRootSource

Arguments

:: (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.

Methods

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.

Instances

class Monad m => CloseOps h m whereSource

Class used to abstract close and flush operations on handles.

Methods

hClose :: h -> m ()Source

hFlush :: h -> m ()Source

Instances

CloseOps Handle IO 
LabelState l p s => CloseOps (LHandle l) (LIO l p s) 

class CloseOps h m => HandleOps h b m whereSource

Class used to abstract reading and writing from and to handles, respectively.

Methods

hGet :: h -> Int -> m bSource

hGetNonBlocking :: h -> Int -> m bSource

hGetContents :: h -> m bSource

hPut :: h -> b -> m ()Source

hPutStr :: h -> b -> m ()Source

hPutStrLn :: h -> b -> m ()Source

Instances

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

data LHandle l Source

A labeled handle.

Instances

(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

getDirectoryContentsPSource

Arguments

:: (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.)

createDirectoryPSource

Arguments

:: (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.

openFilePSource

Arguments

:: (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.

hCloseP :: LabelState l p s => p -> LHandle l -> LIO l p s ()Source

Close a labeled file handle.

hFlushP :: LabelState l p s => p -> LHandle l -> LIO l p s ()Source

Flush a labeled file handle.

hGetPSource

Arguments

:: (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.