From ea177ce261fbe2cc1d5529e974b15a2077897821 Mon Sep 17 00:00:00 2001 From: Gregor Kleen Date: Thu, 9 Apr 2015 01:02:06 +0200 Subject: Updated pwutil.md for newer versions --- posts/pwutil.md | 77 +++++++++++++++++---------------------------------------- 1 file changed, 22 insertions(+), 55 deletions(-) diff --git a/posts/pwutil.md b/posts/pwutil.md index 69a780d..176ffdc 100644 --- a/posts/pwutil.md +++ b/posts/pwutil.md @@ -9,7 +9,8 @@ A long time ago I wrote a bunch of scripts (first in bash, then zsh, and later p * Support for embedding common operation in any kind of record keeping Thus support for almost any encryption known to man (with absolutely no online security), version control, and synchronisation - * [Human readable](https://en.wikipedia.org/wiki/YAML) backstore + * [Human read- and writeable](https://en.wikipedia.org/wiki/YAML) backstore + * Machine parseable output * [Command Line Interface](https://en.wikipedia.org/wiki/Command-line_interface)-only * New accounts can be partially generated by user defined functions with out of the box support for [pwgen](http://sourceforge.net/projects/pwgen/) and SSH @@ -17,7 +18,7 @@ A long time ago I wrote a bunch of scripts (first in bash, then zsh, and later p ~~~ pwget [ …] -Looks up and returns all accounts whose identifier contains any — case insensitive. +Looks up and returns all accounts which contain any anywhere in their representation — case insensitive. pwadd [[--gen- [ …] …] --] [ …] Adds an account to the store — does not overwrite. @@ -35,7 +36,6 @@ pwutil ├── PWAdd.hs ├── PWGet.hs ├── PWUtil -│   ├── Encfs.hs │   ├── Extra │   │   ├── PWGen.hs │   │   └── SSHCmd.hs @@ -64,89 +64,56 @@ The derivation takes some arguments (write those in `{}` above): ~ Overwrite `pwutil.hs` with a file path `with ? false` - ~ `` is one of Encfs, Pwgen, or Ssh a the current time. + ~ `` is one of Pwgen, or Ssh a the current time. If `true` wraps executables to have `$PATH` include ``. ### `Types.hs` -`PWLocation` describes the location of a file containing a YAML object mapping human readable identifiers to account information. -`encryption`, which has essentially the same signature as [`withFile`](http://hackage.haskell.org/package/base-4.8.0.0/docs/System-IO.html#v:withFile) wraps all access to the file. -This in an extremely powerful way to deal with any kind of encryption desired (currently I implemented automatic mounting of an [EncFs](http://en.wikipedia.org/wiki/EncFS) container and `plain`, which does nothing. -`create` is used to try and create the location once should access fail due to a file [not existing](http://hackage.haskell.org/package/base-4.8.0.0/docs/System-IO-Error.html#v:doesNotExistErrorType). +Introducing `PW` (much as [xmonad](https://xmonad.org) did with `X`) is an easy way to keep track of the `PWConfig` without resorting to function arguments. +`BackStore` is our (new and improved) way of encapsulating store access in a totally customisable way—`plain`, which is essential `readFile` and `writeFile` as provided by `ByteString`, is provided for convenience in `Util.hs`. +`PWConfig` most importantly contains a definition of generators (called by passing `--gen-…` to `pwadd`). ~~~ {#Types.hs .haskell .numberLines} module PWUtil.Types ( - PWLocation(..), - Encryption(..), PW(..), + BackStore(..), PWConfig(..), Generator(..) ) where -import System.IO (Handle(..), IOMode(..)) import Control.Monad.State import qualified Data.Map as M import Data.Yaml - -data PWLocation = PWLocation - { path :: FilePath - , encryption :: Encryption - , create :: IO () - } - -instance Show PWLocation where - show loc = show $ path loc - -type Encryption = FilePath -> IOMode -> (Handle -> IO ()) -> IO () +import Data.ByteString type PW = StateT PWConfig IO -data PWConfig = PWConfig - { location :: PWLocation - , generators :: M.Map String Generator - } +data BackStore = BackStore + { readContents :: PW ByteString + , writeContents :: ByteString -> PW () + } -type Generator = [String] -> IO Value +data PWConfig = PWConfig + { generators :: M.Map String Generator + , backstore :: BackStore + } + +type Generator = [String] -> PW Value ~~~ ### `pwutil.hs` -is, in a [xmonad](http://xmonad.org) kind of way, the configuration file. +is, in a [xmonad](http://xmonad.org) kind of way, the configuration file—the shipped default is reproduced below as a template for custom configs. ~~~ {#pwutil.hs .haskell .numberLines} import PWUtil import System.FilePath (()) -import qualified Data.Map as M import System.Directory (getHomeDirectory) -pWLocation :: IO PWLocation -pWLocation = do - h <- getHomeDirectory - return PWLocation { path = h "accounts.yaml" - , encryption = plain - , create = createFile $ h "accounts.yaml" - } - -myGenerators :: M.Map String Generator -myGenerators = M.empty - main :: IO () main = do - myLocation <- pWLocation - runPW (PWConfig { location = myLocation, generators = myGenerators }) pwutil -~~~ - -### `Encfs.hs` - -shall serve as an example for a module providing an encryption wrapper. -It exports - -~~~{.haskell} -encfs :: Encfs -> Encryption -encfs (Encfs backStore mountpoint) = … + h <- getHomeDirectory + runPW (emptyConfig { backstore = plain (h "accounts.yaml") }) pwutil ~~~ - -Upon execution it checks whether `mountpoint` is already mounted. -If not it executes `encfs backStore mountpoint` interactively and calls `fusermount -u` after completion. -- cgit v1.2.3