aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sproxy.example.yml5
-rw-r--r--src/Sproxy/Application.hs24
2 files changed, 16 insertions, 13 deletions
diff --git a/sproxy.example.yml b/sproxy.example.yml
index 063f51e..0259dfc 100644
--- a/sproxy.example.yml
+++ b/sproxy.example.yml
@@ -147,11 +147,10 @@ ssl_key: /path/key.pem
# Unix sockets should be secured with proper unix file permissions.
#
# Backend attributes:
-# name - the host name as in the Host HTTP header.
+# name - the domain name as in the Host HTTP header (without optional colon and port).
# May include wildcards * and ?. The first matching
# backend will be used. Examples: "*.example.com", "wiki.corp.com".
-# Optional. Default is "*". Note, that the name must include
-# port number if non-standard.
+# Optional. Default is "*".
# address - backend IP address. Optional. Default is 127.0.0.1.
# port - backend TCP port. Required unless unix socket is defined.
# socket - unix socket. Highly recommended for security reasons.
diff --git a/src/Sproxy/Application.hs b/src/Sproxy/Application.hs
index ad3bec7..7376657 100644
--- a/src/Sproxy/Application.hs
+++ b/src/Sproxy/Application.hs
@@ -55,14 +55,13 @@ import qualified Sproxy.Logging as Log
redirect :: Word16 -> W.Application
redirect p req resp =
- case W.requestHeaderHost req of
+ case requestDomain req of
Nothing -> badRequest "missing host" req resp
- Just host -> do
+ Just domain -> do
Log.info $ "redirecting to " ++ show location ++ ": " ++ showReq req
resp $ W.responseBuilder status [(hLocation, location)] mempty
where
status = if W.requestMethod req == methodGet then movedPermanently301 else temporaryRedirect307
- (domain, _) = BS.break (== _colon) host
newhost = if p == 443 then domain else domain <> ":" <> pack (show p)
location = "https://" <> newhost <> W.rawPathInfo req <> W.rawQueryString req
@@ -70,10 +69,10 @@ redirect p req resp =
sproxy :: ByteString -> Database -> HashMap Text OAuth2Client -> [(Pattern, BackendConf, BE.Manager)] -> W.Application
sproxy key db oa2 backends = logException $ \req resp -> do
Log.debug $ "sproxy <<< " ++ showReq req
- case W.requestHeaderHost req of
+ case requestDomain req of
Nothing -> badRequest "missing host" req resp
- Just host ->
- case find (\(p, _, _) -> match p (unpack host)) backends of
+ Just domain ->
+ case find (\(p, _, _) -> match p (unpack domain)) backends of
Nothing -> notFound "backend" req resp
Just (_, be, mgr) -> do
let cookieName = pack $ beCookieName be
@@ -145,8 +144,7 @@ extractCookie key now name req = do
authenticate :: ByteString -> BackendConf -> AuthUser -> ByteString -> W.Application
authenticate key be user path req resp = do
now <- epochTime
- let host = fromJust $ W.requestHeaderHost req
- domain = pack <$> beCookieDomain be
+ let domain = pack <$> beCookieDomain be
expiry = now + CTime (beCookieMaxAge be)
authCookie = AuthCookie { acUser = user, acExpiry = expiry }
cookie = WC.def {
@@ -160,7 +158,7 @@ authenticate key be user path req resp = do
, WC.setCookieExpires = Just . posixSecondsToUTCTime . realToFrac $ expiry
}
resp $ W.responseLBS seeOther303 [
- (hLocation, "https://" <> host <> path)
+ (hLocation, "https://" <> fromJust (W.requestHeaderHost req) <> path)
, ("Set-Cookie", toByteString $ WC.renderSetCookie cookie)
] ""
@@ -169,7 +167,7 @@ authorize :: Database -> (AuthCookie, Cookies) -> W.Request -> IO (Maybe W.Reque
authorize db (authCookie, otherCookies) req = do
let
user = acUser authCookie
- domain = decodeUtf8 . fromJust $ W.requestHeaderHost req
+ domain = decodeUtf8 . fromJust $ requestDomain req
email = getEmail user
emailUtf8 = getEmailUtf8 user
familyUtf8 = getFamilyNameUtf8 user
@@ -388,6 +386,12 @@ redirectURL req provider =
<> "/.sproxy/oauth2/" <> encodeUtf8 provider
+requestDomain :: W.Request -> Maybe ByteString
+requestDomain req = do
+ h <- W.requestHeaderHost req
+ return . fst . BS.break (== _colon) $ h
+
+
-- XXX: make sure not to reveal the cookie, which can be valid (!)
showReq :: W.Request -> String
showReq req =