diff options
Diffstat (limited to 'lib/GnuPGAgent.hs')
-rw-r--r-- | lib/GnuPGAgent.hs | 41 |
1 files changed, 34 insertions, 7 deletions
diff --git a/lib/GnuPGAgent.hs b/lib/GnuPGAgent.hs index 8bffd1b..165fdf2 100644 --- a/lib/GnuPGAgent.hs +++ b/lib/GnuPGAgent.hs | |||
@@ -3,6 +3,8 @@ | |||
3 | {-# LANGUAGE PatternGuards #-} | 3 | {-# LANGUAGE PatternGuards #-} |
4 | module GnuPGAgent | 4 | module GnuPGAgent |
5 | ( session | 5 | ( session |
6 | , Query(..) | ||
7 | , QueryMode(..) | ||
6 | , getPassphrase | 8 | , getPassphrase |
7 | , clearPassphrase | 9 | , clearPassphrase |
8 | , quit ) where | 10 | , quit ) where |
@@ -44,6 +46,12 @@ session = do | |||
44 | connect sock (SockAddrUnix (gpghome ++ "/S.gpg-agent")) | 46 | connect sock (SockAddrUnix (gpghome ++ "/S.gpg-agent")) |
45 | agent <- socketToHandle sock ReadWriteMode | 47 | agent <- socketToHandle sock ReadWriteMode |
46 | hSetBuffering agent LineBuffering | 48 | hSetBuffering agent LineBuffering |
49 | lookupEnv "DISPLAY" >>= \case | ||
50 | Just display -> do hPutStrLn agent ("option putenv DISPLAY="++display) | ||
51 | _ <- hGetLine agent | ||
52 | return () | ||
53 | Nothing -> return () | ||
54 | -- TODO: GPG_TTY | ||
47 | return $ Just $ GnuPGAgent agent | 55 | return $ Just $ GnuPGAgent agent |
48 | Nothing -> do | 56 | Nothing -> do |
49 | hPutStrLn stderr "Unable to find home directory." | 57 | hPutStrLn stderr "Unable to find home directory." |
@@ -64,23 +72,42 @@ clearPassphrase agent key = do | |||
64 | let cmd = "clear_passphrase "++fingerprint key | 72 | let cmd = "clear_passphrase "++fingerprint key |
65 | hPutStrLn (agentHandle agent) cmd | 73 | hPutStrLn (agentHandle agent) cmd |
66 | 74 | ||
67 | getPassphrase :: GnuPGAgent -> Bool -> Packet -> String -> Maybe Packet -> IO (Maybe String) | 75 | data Query = Query |
68 | getPassphrase agent ask key uid masterkey = do | 76 | { queryPacket :: Packet |
69 | let askopt = if ask then "" else "--no-ask " | 77 | , queryUID :: String |
70 | (er,pr,desc) = prompts key uid masterkey | 78 | , queryMainKey :: Maybe Packet |
79 | } | ||
80 | deriving Show | ||
81 | |||
82 | data QueryMode = AskNot | AskAgain String | Ask | ||
83 | deriving (Show,Eq,Ord) | ||
84 | |||
85 | getPassphrase :: GnuPGAgent -> QueryMode -> Query -> IO (Maybe String) | ||
86 | getPassphrase agent ask (Query key uid masterkey) = do | ||
87 | let (er0,pr,desc) = prompts key uid masterkey | ||
88 | (er,askopt) = case ask of | ||
89 | AskNot -> (er0,"--no-ask") | ||
90 | AskAgain ermsg -> (ermsg,"") | ||
91 | Ask -> (er0,"") | ||
71 | cmd = "get_passphrase "++askopt++fingerprint key++" "++unwords (map percentPlusEscape [er,pr,desc]) | 92 | cmd = "get_passphrase "++askopt++fingerprint key++" "++unwords (map percentPlusEscape [er,pr,desc]) |
72 | putStrLn cmd | 93 | -- putStrLn cmd |
73 | hPutStrLn (agentHandle agent) cmd | 94 | hPutStrLn (agentHandle agent) cmd |
74 | r0 <- hGetLine (agentHandle agent) | 95 | r0 <- hGetLine (agentHandle agent) |
96 | -- putStrLn $ "agent says: " ++ r0 | ||
75 | case takeWhile (/=' ') r0 of | 97 | case takeWhile (/=' ') r0 of |
76 | "OK" -> hGetLine (agentHandle agent) >>= unhex . drop 3 | 98 | "OK" -> hGetLine (agentHandle agent) >>= unhex . drop 3 |
77 | where | 99 | where |
78 | #if defined(VERSION_memory) | 100 | #if defined(VERSION_memory) |
79 | unhex hx = case convertFromBase Base16 (S8.pack hx) of | 101 | unhex hx = case convertFromBase Base16 (S8.pack hx) of |
80 | Left e -> return Nothing | 102 | Left e -> do |
103 | -- Useful for debugging but insecure generally ;) | ||
104 | -- putStrLn $ "convertFromBase error for input "++show hx++": "++show e | ||
105 | return Nothing | ||
81 | Right bs -> return $ Just $ S8.unpack bs | 106 | Right bs -> return $ Just $ S8.unpack bs |
82 | #elif defined(VERSION_dataenc) | 107 | #elif defined(VERSION_dataenc) |
83 | unhex hx = return $ fmap (map $ chr . fromIntegral) $ Base16.decode hx | 108 | unhex hx = maybe (return () {- putStrLn $ "dataenc error for input "++show hx -}) |
109 | return | ||
110 | $ fmap (map $ chr . fromIntegral) $ Base16.decode hx | ||
84 | #endif | 111 | #endif |
85 | "ERR" -> return Nothing | 112 | "ERR" -> return Nothing |
86 | 113 | ||