Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
412c8312b0 | ||
|
|
012486c045 | ||
|
|
cdff8c8917 | ||
|
|
f305822ae1 | ||
|
|
7cf0b34078 | ||
|
|
191be38fbe | ||
|
|
f2ae7bca76 |
@@ -1,6 +1,12 @@
|
|||||||
# Changelog for passman
|
# Changelog for passman
|
||||||
|
|
||||||
## Unreleased changes
|
## 0.2
|
||||||
|
|
||||||
|
- implemented manual saving
|
||||||
|
- added a warning when changing master password
|
||||||
|
- some code cleanup as suggested by [Stephen Paul Weber](https://github.com/singpolyma)
|
||||||
|
|
||||||
|
## 0.1.1
|
||||||
|
|
||||||
- corrected a bug that was causing the pwGenerate function to hang occasionally.
|
- corrected a bug that was causing the pwGenerate function to hang occasionally.
|
||||||
- this may cause some passwords to be generated differently
|
- this may cause some passwords to be generated differently
|
||||||
|
|||||||
11
app/UI.hs
11
app/UI.hs
@@ -63,6 +63,7 @@ mainMenu =
|
|||||||
[ ( "add a password", addPassword )
|
[ ( "add a password", addPassword )
|
||||||
, ( "view/edit a password", viewEditMenu )
|
, ( "view/edit a password", viewEditMenu )
|
||||||
, ( "change master password", changeMasterPass )
|
, ( "change master password", changeMasterPass )
|
||||||
|
, ( "save manually", save >> mainMenu )
|
||||||
, ( "lock session", lockSession )
|
, ( "lock session", lockSession )
|
||||||
, ( "quit", quit )
|
, ( "quit", quit )
|
||||||
]
|
]
|
||||||
@@ -93,9 +94,13 @@ viewEditMenu = menu "View/Edit Password"
|
|||||||
|
|
||||||
changeMasterPass :: S.StateT Status IO ()
|
changeMasterPass :: S.StateT Status IO ()
|
||||||
changeMasterPass = do
|
changeMasterPass = do
|
||||||
oldP <- S.gets $ view masterPass
|
req (confirm $
|
||||||
newP <- req $ reqDefault getMasterPass oldP
|
"\nWARNING: Changing your master password will change all of your saved passwords.\n" ++
|
||||||
S.modify $ set masterPass newP
|
"Are you sure you would like to proceed?") >>= flip when
|
||||||
|
(do
|
||||||
|
oldP <- S.gets $ view masterPass
|
||||||
|
newP <- req $ reqDefault getMasterPass oldP
|
||||||
|
S.modify $ set masterPass newP)
|
||||||
mainMenu
|
mainMenu
|
||||||
|
|
||||||
lockSession :: S.StateT Status IO ()
|
lockSession :: S.StateT Status IO ()
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name: passman
|
name: passman
|
||||||
version: 0.1.1
|
version: 0.2
|
||||||
github: "jlamothe/passman"
|
github: "jlamothe/passman"
|
||||||
license: LGPL-3
|
license: LGPL-3
|
||||||
author: "Jonathan Lamothe"
|
author: "Jonathan Lamothe"
|
||||||
@@ -30,6 +30,7 @@ dependencies:
|
|||||||
library:
|
library:
|
||||||
source-dirs: src
|
source-dirs: src
|
||||||
dependencies:
|
dependencies:
|
||||||
|
- base16-bytestring
|
||||||
- base64-bytestring
|
- base64-bytestring
|
||||||
- SHA
|
- SHA
|
||||||
- text
|
- text
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ License along with this program. If not, see
|
|||||||
-}
|
-}
|
||||||
|
|
||||||
{-# LANGUAGE TemplateHaskell #-}
|
{-# LANGUAGE TemplateHaskell #-}
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
|
|
||||||
module Password (
|
module Password (
|
||||||
-- * Data Types
|
-- * Data Types
|
||||||
@@ -59,6 +59,7 @@ import Data.Aeson
|
|||||||
, (.=)
|
, (.=)
|
||||||
)
|
)
|
||||||
import qualified Data.ByteString.Lazy as B
|
import qualified Data.ByteString.Lazy as B
|
||||||
|
import qualified Data.ByteString.Base16.Lazy as B16
|
||||||
import qualified Data.ByteString.Base64.Lazy as B64
|
import qualified Data.ByteString.Base64.Lazy as B64
|
||||||
import Data.Char (isUpper, isLower, isDigit, isAlphaNum, toLower)
|
import Data.Char (isUpper, isLower, isDigit, isAlphaNum, toLower)
|
||||||
import Data.Digest.Pure.SHA
|
import Data.Digest.Pure.SHA
|
||||||
@@ -322,12 +323,13 @@ isSpecial :: Char -> Bool
|
|||||||
isSpecial = not . isAlphaNum
|
isSpecial = not . isAlphaNum
|
||||||
|
|
||||||
mkPass :: String -> PWPolicy -> String
|
mkPass :: String -> PWPolicy -> String
|
||||||
mkPass (x:xs) p = let p' = nextPolicy x p in
|
mkPass [] _ = "" -- this should never happen
|
||||||
if p^.pwLength <= 0
|
mkPass (x:xs) p = if p^.pwLength <= 0
|
||||||
then ""
|
then ""
|
||||||
else if validatePWPolicy p'
|
else let p' = nextPolicy x p in
|
||||||
then x : mkPass xs p'
|
if validatePWPolicy p'
|
||||||
else mkPass xs p
|
then x : mkPass xs p'
|
||||||
|
else mkPass xs p
|
||||||
|
|
||||||
mkPool :: B.ByteString -> String
|
mkPool :: B.ByteString -> String
|
||||||
mkPool = toB64 . raw where
|
mkPool = toB64 . raw where
|
||||||
@@ -338,10 +340,7 @@ mkSeed :: String -> PWData -> B.ByteString
|
|||||||
mkSeed pw d = toUTF8 pw `B.append` (d^.pwSalt)
|
mkSeed pw d = toUTF8 pw `B.append` (d^.pwSalt)
|
||||||
|
|
||||||
mkHash :: B.ByteString -> B.ByteString
|
mkHash :: B.ByteString -> B.ByteString
|
||||||
mkHash = raw . show . sha256 where
|
mkHash = fst . B16.decode . encodeUtf8 . T.pack . show . sha256
|
||||||
raw (x:y:xs) = read ("0x" ++ [x] ++ [y]) `B.cons` raw xs
|
|
||||||
raw [_] = error "odd number of hex digits in hash"
|
|
||||||
raw "" = B.empty
|
|
||||||
|
|
||||||
nextPolicy :: Char -> PWPolicy -> PWPolicy
|
nextPolicy :: Char -> PWPolicy -> PWPolicy
|
||||||
nextPolicy x p = over pwLength pred $
|
nextPolicy x p = over pwLength pred $
|
||||||
|
|||||||
Reference in New Issue
Block a user