-- hokey.hs: hOpenPGP key tool
-- Copyright © 2013-2026 Clint Adams
--
-- vim: softtabstop=4:shiftwidth=4:expandtab
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU Affero General Public License as
-- published by the Free Software Foundation, either version 3 of the
-- License, or (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU Affero General Public License for more details.
--
-- You should have received a copy of the GNU Affero General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE TypeApplications #-}
import HOpenPGP.Tools.Common.Common (banner, versioner, warranty)
import Options.Applicative.Builder
( command
, footerDoc
, headerDoc
, info
, prefs
, progDesc
, showHelpOnError
)
import Options.Applicative.Extra (customExecParser, helper, hsubparser)
import Options.Applicative.Types (Parser)
import System.IO
( BufferMode(..)
, Handle
, hFlush
, hSetBuffering
, stderr
)
import Prettyprinter (hardline)
import qualified Prettyprinter.Render.Terminal as PPA
import HOpenPGP.Tools.Hokey.Options
( FetchOptions
, InjectSSHAgentOptions
, LintOptions
, fetchO
, injectSSHAgentO
, lintO
)
import HOpenPGP.Tools.Hokey.Canonicalize (doCanonicalize)
import HOpenPGP.Tools.Hokey.Fetch (doFetch)
import HOpenPGP.Tools.Hokey.InjectSSHAgent (doInjectSSHAgent)
import HOpenPGP.Tools.Hokey.Lint (doLint)
data Command
= CmdLint LintOptions
| CmdCanonicalize
| CmdFetch FetchOptions
| CmdInjectSSHAgent InjectSSHAgentOptions
dispatch :: Command -> IO ()
dispatch (CmdFetch o) = banner' stderr >> hFlush stderr >> doFetch o
dispatch (CmdLint o) = banner' stderr >> hFlush stderr >> doLint o
dispatch CmdCanonicalize = banner' stderr >> hFlush stderr >> doCanonicalize
dispatch (CmdInjectSSHAgent o) =
banner' stderr >> hFlush stderr >> doInjectSSHAgent o
main :: IO ()
main = do
hSetBuffering stderr LineBuffering
customExecParser
(prefs showHelpOnError)
(info
(helper <*> versioner "hokey" <*> cmd)
(headerDoc (Just (banner "hokey")) <>
progDesc "hOpenPGP Key utility" <>
footerDoc (Just (warranty "hokey")))) >>=
dispatch
cmd :: Parser Command
cmd =
hsubparser
(command
"canonicalize"
(info
(pure CmdCanonicalize)
(progDesc "arrange key components in a canonical ordering")) <>
command
"fetch"
(info
(CmdFetch <$> fetchO)
(progDesc "fetch key(s) via HKP or WKD")) <>
command
"inject-ssh-agent"
(info
(CmdInjectSSHAgent <$> injectSSHAgentO)
(progDesc "Read exported secret key bytes, pick an auth-capable subkey, and add it to ssh-agent")) <>
command
"lint"
(info (CmdLint <$> lintO) (progDesc "check key(s) for 'best practices'")))
banner' :: Handle -> IO ()
banner' h =
PPA.hPutDoc h (banner "hokey" <> hardline <> warranty "hokey" <> hardline)