6 Commits

Author SHA1 Message Date
a45a75c3e2 get the client certificate from the connection's context
...instead of the janky thing we were doing before
2023-01-04 10:26:56 -05:00
77cfcce5df version 0.1.0.1 2023-01-04 10:09:48 -05:00
115dcf3998 Merge pull request 'catch *any* exception' (#3) from crashfix into dev
Reviewed-on: https://codeberg.org/jlamothe/gemcap/pulls/3
2023-01-04 15:02:01 +00:00
554efdabcb catch *any* exception
`listenLoop` was crashing when the client closed the connection during the handshake.  How this doesn't qualify as an `IOException` is beyond me.
2023-01-01 11:52:59 -05:00
a69a9385b6 use tls 1.5.8 (or better) 2022-12-31 09:25:02 -05:00
fa8ef1104a use current LTS resolver 2022-12-31 01:17:30 -05:00
6 changed files with 35 additions and 57 deletions

View File

@@ -1,3 +1,6 @@
# Changelog for gemcap # Changelog for gemcap
## Unreleased changes ## 0.1.0.1
- updated underlying libraries to more current versions
- fixed a bug that would cause the server to crash when the client aborted the handshake by rejecting the key

View File

@@ -1,11 +1,11 @@
cabal-version: 2.2 cabal-version: 2.2
-- This file has been generated from package.yaml by hpack version 0.34.4. -- This file has been generated from package.yaml by hpack version 0.35.0.
-- --
-- see: https://github.com/sol/hpack -- see: https://github.com/sol/hpack
name: gemcap name: gemcap
version: 0.1.0 version: 0.1.0.1
synopsis: a simple Gemini capsule (server) synopsis: a simple Gemini capsule (server)
description: a simple Gemini capsule (server) - see README.md for details description: a simple Gemini capsule (server) - see README.md for details
category: Gemini category: Gemini
@@ -34,12 +34,12 @@ library
ghc-options: -Wall ghc-options: -Wall
build-depends: build-depends:
base >=4.7 && <5 base >=4.7 && <5
, bytestring >=0.10.12.0 && <0.11 , bytestring >=0.11.3.1 && <0.12
, io-streams , io-streams
, network , network
, tcp-streams >=1.0.1.1 && <1.1 , tcp-streams >=1.0.1.1 && <1.1
, text >=1.2.4.1 && <1.3 , text >=1.2.4.1 && <1.3
, tls , tls >=1.5.8 && <1.6
, transformers , transformers
, x509 , x509
default-language: Haskell2010 default-language: Haskell2010
@@ -58,14 +58,14 @@ test-suite gemcap-test
ghc-options: -Wall -threaded -rtsopts -with-rtsopts=-N ghc-options: -Wall -threaded -rtsopts -with-rtsopts=-N
build-depends: build-depends:
base >=4.7 && <5 base >=4.7 && <5
, bytestring >=0.10.12.0 && <0.11 , bytestring >=0.11.3.1 && <0.12
, gemcap , gemcap
, hspec >=2.7.10 && <2.8 , hspec >=2.9.7 && <2.10
, io-streams , io-streams
, network , network
, tcp-streams >=1.0.1.1 && <1.1 , tcp-streams >=1.0.1.1 && <1.1
, text >=1.2.4.1 && <1.3 , text >=1.2.4.1 && <1.3
, tls , tls >=1.5.8 && <1.6
, transformers , transformers
, x509 , x509
default-language: Haskell2010 default-language: Haskell2010

View File

@@ -1,5 +1,5 @@
name: gemcap name: gemcap
version: 0.1.0 version: 0.1.0.1
license: AGPL-3.0-or-later license: AGPL-3.0-or-later
author: "Jonathan Lamothe" author: "Jonathan Lamothe"
maintainer: "jonathan@jlamothe.net" maintainer: "jonathan@jlamothe.net"
@@ -25,12 +25,12 @@ ghc-options:
dependencies: dependencies:
- base >= 4.7 && < 5 - base >= 4.7 && < 5
- bytestring >= 0.10.12.0 && < 0.11 - bytestring >= 0.11.3.1 && < 0.12
- tcp-streams >= 1.0.1.1 && < 1.1 - tcp-streams >= 1.0.1.1 && < 1.1
- text >= 1.2.4.1 && < 1.3 - text >= 1.2.4.1 && < 1.3
- io-streams - io-streams
- network - network
- tls - tls >= 1.5.8 && < 1.6
- transformers - transformers
- x509 - x509
@@ -49,6 +49,6 @@ tests:
- -with-rtsopts=-N - -with-rtsopts=-N
dependencies: dependencies:
- gemcap - gemcap
- hspec >= 2.7.10 && < 2.8 - hspec >= 2.9.7 && < 2.10
verbatim: verbatim:
<<: *paths <<: *paths

View File

@@ -31,15 +31,15 @@ module Network.Gemini.Capsule (
) where ) where
import Control.Concurrent (forkIO) import Control.Concurrent (forkIO)
import Control.Exception (IOException, try) import Control.Exception (SomeException, try)
import Control.Exception.Base (bracket, finally) import Control.Exception.Base (bracket, finally)
import Control.Monad (void) import Control.Monad (void)
import Control.Monad.Trans.Maybe (MaybeT (..), runMaybeT)
import qualified Data.Connection as C import qualified Data.Connection as C
import Data.IORef (IORef, newIORef, readIORef, writeIORef)
import Data.TLSSetting (makeServerParams) import Data.TLSSetting (makeServerParams)
import Data.X509 (Certificate, CertificateChain (..), getSigned, signedObject) import Data.X509 (CertificateChain (..), getSigned, signedObject)
import qualified Network.Socket as S import qualified Network.Socket as S
import Network.TLS (ServerParams, onClientCertificate, serverHooks) import Network.TLS (ServerParams, getClientCertificateChain)
import System.IO.Streams.TCP (bindAndListen) import System.IO.Streams.TCP (bindAndListen)
import System.IO.Streams.TLS (accept) import System.IO.Streams.TLS (accept)
@@ -69,32 +69,18 @@ runGemCapsule settings handler = bracket
listenLoop :: S.Socket -> ServerParams -> GemHandler -> IO a listenLoop :: S.Socket -> ServerParams -> GemHandler -> IO a
listenLoop sock params handler = do listenLoop sock params handler = do
certRef <- newIORef Nothing try (accept params sock) >>= \case
let params' = adjustServerParams certRef params Left (_::SomeException) -> return ()
try (accept params' sock) >>= \case
Left (_::IOException) -> return ()
Right conn -> void $ forkIO $ finally Right conn -> void $ forkIO $ finally
(readIORef certRef >>= runConnection conn handler) ( do
let (context, _) = C.connExtraInfo conn
mCert <- runMaybeT $
MaybeT (getClientCertificateChain context) >>= \case
CertificateChain [] -> fail "no certificate"
CertificateChain (se:_) -> return $ signedObject $ getSigned se
runConnection conn handler mCert
)
(C.close conn) (C.close conn)
listenLoop sock params handler listenLoop sock params handler
adjustServerParams
:: IORef (Maybe Certificate)
-> ServerParams
-> ServerParams
adjustServerParams certRef params = let
hooks = serverHooks params
certHook = onClientCertificate hooks
certHook' chain = do
case chain of
CertificateChain [] -> return ()
CertificateChain (se:_) -> do
let cert = signedObject $ getSigned se
writeIORef certRef (Just cert)
certHook chain
hooks' = hooks { onClientCertificate = certHook' }
in params { serverHooks = hooks' }
--jl --jl

View File

@@ -17,8 +17,7 @@
# #
# resolver: ./custom-snapshot.yaml # resolver: ./custom-snapshot.yaml
# resolver: https://example.com/snapshots/2018-01-01.yaml # resolver: https://example.com/snapshots/2018-01-01.yaml
resolver: resolver: lts-20.5
url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/18/13.yaml
# User packages to be built. # User packages to be built.
# Various formats can be used as shown in the example below. # Various formats can be used as shown in the example below.
@@ -40,8 +39,6 @@ packages:
# - git: https://github.com/commercialhaskell/stack.git # - git: https://github.com/commercialhaskell/stack.git
# commit: e7b331f14bcffb8367cd58fbfc8b40ec7642100a # commit: e7b331f14bcffb8367cd58fbfc8b40ec7642100a
# #
extra-deps:
- tcp-streams-1.0.1.1@sha256:35e9ecfa515797052f8c3c01834d2daebd5e93f3152c7fc98b32652bf6f0c052,2329
# Override default flag values for local packages and extra-deps # Override default flag values for local packages and extra-deps
# flags: {} # flags: {}

View File

@@ -3,18 +3,10 @@
# For more information, please see the documentation at: # For more information, please see the documentation at:
# https://docs.haskellstack.org/en/stable/lock_files # https://docs.haskellstack.org/en/stable/lock_files
packages: packages: []
- completed:
hackage: tcp-streams-1.0.1.1@sha256:35e9ecfa515797052f8c3c01834d2daebd5e93f3152c7fc98b32652bf6f0c052,2329
pantry-tree:
size: 1004
sha256: 572071fca40a0b6c4cc950d10277a6f12e83cf4846882b6ef83fcccaa2c18c45
original:
hackage: tcp-streams-1.0.1.1@sha256:35e9ecfa515797052f8c3c01834d2daebd5e93f3152c7fc98b32652bf6f0c052,2329
snapshots: snapshots:
- completed: - completed:
size: 586268 sha256: a684cdbdf9304b325a503e0fe1d9648e9c18155ce4c7cfebbe8a7f93674e6295
url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/18/13.yaml size: 649106
sha256: d9e658a22cfe8d87a64fdf219885f942fef5fe2bcb156a9800174911c5da2443 url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/20/5.yaml
original: original: lts-20.5
url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/18/13.yaml