From 65c9d549c1760cad63c42120ee95a64cff583211 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20Br=C3=A9chemier?= Date: Fri, 29 Sep 2017 04:54:50 +0200 Subject: [PATCH] Read secret file as binary, without premature parsing as UTF-8 (#876) (#988) --- CHANGELOG.md | 1 + main/Main.hs | 17 ++++++++++------- test/io-tests.sh | 10 +++++----- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 377c15b03..2b1491069 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Fixed +- #876, Read secret files as binary, discard final LF if any - @eric-brechemier - #968, Treat blank proxy uri as missing - @begriffs - #933, OpenAPI externals docs url to current version - @steve-chavez - #962, OpenAPI don't err on nonexistent schema - @steve-chavez diff --git a/main/Main.hs b/main/Main.hs index 98869060b..161ae8887 100644 --- a/main/Main.hs +++ b/main/Main.hs @@ -16,13 +16,14 @@ import Protolude hiding (replace, hPutStrLn) import Control.Retry (RetryStatus, capDelay, exponentialBackoff, retrying, rsPreviousDelay) -import Data.ByteString.Base64 (decode) import Data.IORef (IORef, atomicWriteIORef, newIORef, readIORef) import Data.String (IsString (..)) import Data.Text (pack, replace, stripPrefix, strip) import Data.Text.Encoding (decodeUtf8, encodeUtf8) -import Data.Text.IO (hPutStrLn, readFile) +import Data.Text.IO (hPutStrLn) +import qualified Data.ByteString.Base64 as B64 +import qualified Data.ByteString as BS import qualified Hasql.Decoders as HD import qualified Hasql.Encoders as HE import qualified Hasql.Pool as P @@ -264,14 +265,16 @@ loadSecretFile conf = extractAndTransform mSecret fmap setSecret $ transformString isB64 =<< case stripPrefix "@" secret of - Nothing -> return secret - Just filename -> readFile (toS filename) + Nothing -> return . encodeUtf8 $ secret + Just filename -> chomp <$> BS.readFile (toS filename) + where + chomp bs = fromMaybe bs (BS.stripSuffix "\n" bs) -- -- Turns the Base64url encoded JWT into Base64 - transformString :: Bool -> Text -> IO ByteString - transformString False t = return . encodeUtf8 $ t + transformString :: Bool -> ByteString -> IO ByteString + transformString False t = return t transformString True t = - case decode (encodeUtf8 $ strip $ replaceUrlChars t) of + case B64.decode $ encodeUtf8 $ strip $ replaceUrlChars $ decodeUtf8 t of Left errMsg -> panic $ pack errMsg Right bs -> return bs setSecret bs = conf {configJwtSecret = Just bs} diff --git a/test/io-tests.sh b/test/io-tests.sh index 06d802933..0cf3250f3 100755 --- a/test/io-tests.sh +++ b/test/io-tests.sh @@ -93,13 +93,13 @@ totalTests=12 echo "1..$totalTests" readSecretFromFile word.noeol 'simple (no EOL)' -skip readSecretFromFile word.txt 'simple' +readSecretFromFile word.txt 'simple' readSecretFromFile ascii.noeol 'ASCII (no EOL)' -skip readSecretFromFile ascii.txt 'ASCII' +readSecretFromFile ascii.txt 'ASCII' readSecretFromFile utf8.noeol 'UTF-8 (no EOL)' -skip readSecretFromFile utf8.txt 'UTF-8' -skip readSecretFromFile binary.noeol 'binary' -skip readSecretFromFile binary.eol 'binary (+EOL)' +readSecretFromFile utf8.txt 'UTF-8' +readSecretFromFile binary.noeol 'binary' +readSecretFromFile binary.eol 'binary (+EOL)' readSecretFromFile word.b64 'Base64 (simple)' readSecretFromFile ascii.b64 'Base64 (ASCII)'