packages feed

wordpass-1.0.0.0: WordPass.hs

{-# LANGUAGE TemplateHaskell, NoMonomorphismRestriction #-}
-- | Main module generating passwords.
module Main where

import qualified Data.Text.IO as Text
import qualified Data.Set     as Set
import           Data.Random.Sample
import           Data.Random.RVar.Enum()
import           Data.Random.Source.DevRandom
import           Data.Random.Source.IO()
import qualified Data.Vector  as V
import           Control.Applicative
import           Control.Monad       (replicateM_)
import           HFlags
import           Text.WordPass

-- * Command-line flags
-- | Number of words per password
defineFlag "w:words" (4 :: Int) "Number of words for each password."

-- | Number of passwords
defineFlag "p:passwords" (10 :: Int) "Number of passwords to generate."

-- | Default word list directory.
defineFlag "d:directory" ("/usr/share/dict" :: FilePath) "Default directory to search for dictionaries\n (works only if --wordlist options is NOT USED.)"

-- | Pick specific wordlist.
defineFlag "l:wordlist" ("" :: FilePath) "Select particular dictionary (filepath)."

-- | Pick specific wordlist.
defineFlag "t:pseudorandom" (False :: Bool) "Generate passwords using StdRandom generator, instead of DevRandom. (Faster, but less safe. Good for testing."

-- | Fake flag to avoid GHC losing the last instance declaration
defineFlag "fakeflag" (False :: Bool) "This flag does nothing and is never used"


-- | Read wordlist given by explict filepath, or search for all wordlists in a given directory.
selectWordList :: FilePath -> FilePath -> IO WordSet
selectWordList ""       dir = readDictDir dir
selectWordList filename _   = readDict    filename

main :: IO ()
main = do _args <- $initHFlags "WordPass - dictionary-based password generator"
          dictWords <- (V.fromList . Set.toList) <$> selectWordList flags_wordlist flags_directory
          putStrLn  $ "Read " ++ show (V.length dictWords) ++ " words from dictionaries."
          putStr "Estimated password strength (bits): "
          print $ randomPasswordStrength dictWords flags_words
          replicateM_ flags_passwords $ do 
            let rand = randomPassword dictWords flags_words
            rv <- if flags_pseudorandom
                    then sample rand
                    else sampleFrom DevRandom rand
            Text.putStrLn rv