1
0
mirror of https://github.com/redelmann/scat synced 2025-01-09 22:24:19 +01:00

Added possibility to enter an extra code (typically a long code, written down on a card).

This commit is contained in:
Romain Edelmann 2013-08-11 20:18:11 +02:00
parent 248c2ca707
commit f80b4347a6
3 changed files with 45 additions and 12 deletions

View File

@ -10,7 +10,7 @@ name: scat
-- PVP summary: +-+------- breaking API changes
-- | | +----- non-breaking API additions
-- | | | +--- code changes with no API change
version: 0.2.0.0
version: 0.2.1.0
-- A short (one-line) description of the package.
synopsis: Generates unique passwords for various websites from a single password.

View File

@ -3,6 +3,7 @@
-- | Password scatterer.
module Main (main) where
import Data.Monoid
import Data.ByteString (ByteString)
import Data.ByteString (unpack)
import qualified Data.ByteString.Char8 as C
@ -17,9 +18,9 @@ import Scat.Builder
import Scat.Options
-- | Generates the seed integer given a key and a password.
scatter :: ByteString -> ByteString -> Integer
scatter k pw = foldr (\ c s -> fromIntegral c + 256 * s) 0 $
unpack $ unHash $ scrypt params (Salt k) (Pass pw)
scatter :: ByteString -> ByteString -> ByteString -> Integer
scatter k pw c = foldr (\ n s -> fromIntegral n + 256 * s) 0 $
unpack $ unHash $ scrypt params (Salt k) (Pass $ pw <> c)
where
Just params = scryptParams 14 8 50
@ -41,8 +42,9 @@ scat = do
k <- getKey
s <- getSchema
pw <- getPassword
c <- getCode
printVerbose "Generated password:\n"
liftIO $ putStrLn $ evalBuilder s $ scatter k pw
liftIO $ putStrLn $ evalBuilder s $ scatter k pw c
-- | Prints, if the verbosity level allows it.
printVerbose :: String -> Scat ()
@ -67,11 +69,11 @@ getPassword = do
-- Retrieve the password from the arguments.
Just st -> return $ C.pack st
where
getPass = askPassword "Password: "
getPass = askPassword False "Password: "
getPassConfirm = do
a <- askPassword "Password: "
b <- askPassword "Confirm: "
a <- askPassword False "Password: "
b <- askPassword False "Confirm: "
if a == b
then return a
else do
@ -79,21 +81,33 @@ getPassword = do
getPassConfirm
-- | Ask a password on the command line, with the specified prompt.
askPassword :: String -> Scat C.ByteString
askPassword str = do
askPassword :: Bool -> String -> Scat ByteString
askPassword echo str = do
printVerbose str
old <- liftIO $ hGetEcho stdin
pw <- liftIO $ bracket_
(hSetEcho stdin False)
(hSetEcho stdin echo)
(hSetEcho stdin old)
C.getLine
printVerbose "\n"
unless echo $ printVerbose "\n"
return pw
-- | Gets the key.
getKey :: Scat ByteString
getKey = fmap (C.pack . key) ask
-- | Gets the code.
getCode :: Scat ByteString
getCode = do
uc <- fmap useCode ask
if uc
then do
mc <- fmap code ask
case mc of
Just st -> return $ C.pack st
Nothing -> askPassword True "Code: "
else return ""
-- | Gets the schema to generate the new password.
getSchema :: Scat Schema
getSchema = do

View File

@ -8,6 +8,8 @@ module Scat.Options
-- * Accessors
, password
, key
, useCode
, code
, schema
, verbose
, confirm
@ -17,6 +19,7 @@ module Scat.Options
) where
import Data.Monoid
import Data.Maybe (isJust)
import Options.Applicative
-- | All program options.
@ -25,6 +28,10 @@ data Options = Options
-- ^ Password, optionally provided.
, key :: String
-- ^ Key or category for the password.
, useCode_ :: Bool
-- ^ Indicates if extra code should be used.
, code :: Maybe String
-- ^ Extra code. Activates code usage.
, schema :: String
-- ^ Name of the schema to use.
, verbose_ :: Bool
@ -33,6 +40,10 @@ data Options = Options
-- ^ Indicates if the password must be confirmed. Activates verbosity.
}
-- | Indicates if extra code should be used.
useCode :: Options -> Bool
useCode opts = useCode_ opts || isJust (code opts)
{- | Verbosity. If false, do not print anything but the generated password.
True when @--verbose@ or @--confirmation@ are specified. -}
verbose :: Options -> Bool
@ -60,6 +71,14 @@ options = Options
<> long "key"
<> help "Key associated (website, email address, ...) (mandatory)"
<> metavar "KEY")
<*> switch
(short 'x'
<> long "extra"
<> help "Indicates extra code should be used.")
<*> optional
(strOption (long "code"
<> help "Extra code."
<> metavar "CODE"))
<*> strOption
(short 's'
<> long "schema"