mirror of
https://github.com/redelmann/scat
synced 2025-01-10 06:34:20 +01:00
Added possibility to enter an extra code (typically a long code, written down on a card).
This commit is contained in:
parent
248c2ca707
commit
f80b4347a6
@ -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.
|
||||
|
36
src/Scat.hs
36
src/Scat.hs
@ -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
|
||||
|
@ -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"
|
||||
|
Loading…
Reference in New Issue
Block a user