import Network.Socket
import Network.HTTP.Client
import Network.HTTP.Client.TLS
+import Text.Read
defaultUserAgent :: U.UserAgent
defaultUserAgent = "git-annex/" ++ BuildInfo.packageversion
manager <- liftIO $ U.newManager $
avoidtimeout $ tlsManagerSettings
return (urldownloader, manager)
- allowedaddrs -> do
+ allowedaddrsports -> do
addrmatcher <- liftIO $
(\l v -> any (\f -> f v) l) . catMaybes
- <$> mapM makeAddressMatcher allowedaddrs
+ <$> mapM (uncurry makeAddressMatcher)
+ (mapMaybe splitAddrPort allowedaddrsports)
-- Default to not allowing access to loopback
-- and private IP addresses to avoid data
-- leakage.
-- separate timeout controls, so disable that.
avoidtimeout s = s { managerResponseTimeout = responseTimeoutNone }
+splitAddrPort :: String -> Maybe (String, Maybe PortNumber)
+splitAddrPort s
+ -- "[addr]:port" (also allow "[addr]")
+ | "[" `isPrefixOf` s = case splitc ']' (drop 1 s) of
+ [a,cp] -> case splitc ':' cp of
+ ["",p] -> do
+ pn <- readMaybe p
+ return (a, Just pn)
+ [""] -> Just (a, Nothing)
+ _ -> Nothing
+ _ -> Nothing
+ | otherwise = Just (s, Nothing)
+
ipAddressesUnlimited :: Annex Bool
ipAddressesUnlimited =
("all" == ) . annexAllowedIPAddresses <$> Annex.getGitConfig
* init --version: When the version given is one that automatically
upgrades to a newer version, use the newer version instead.
* Auto upgrades from older repo versions, like v5, now jump right to v8.
+ * Extended annex.security.allowed-ip-addresses to let specific ports
+ of an IP address to be used, while denying use of other ports.
-- Joey Hess <id@joeyh.name> Wed, 19 Feb 2020 12:48:58 -0400
- match that address in a SockAddr. Nothing when the address cannot be
- parsed.
-
+ - When a port is specified, will only match a SockAddr using the same port.
+ -
- This does not involve any DNS lookups.
-}
-makeAddressMatcher :: String -> IO (Maybe (SockAddr -> Bool))
-makeAddressMatcher s = go
+makeAddressMatcher :: String -> Maybe PortNumber -> IO (Maybe (SockAddr -> Bool))
+makeAddressMatcher s mp = go
<$> catchDefaultIO [] (getAddrInfo (Just hints) (Just s) Nothing)
where
hints = defaultHints
go [] = Nothing
go l = Just $ \sockaddr -> any (match sockaddr) (map addrAddress l)
- match (SockAddrInet _ a) (SockAddrInet _ b) = a == b
- match (SockAddrInet6 _ _ a _) (SockAddrInet6 _ _ b _) = a == b
+ match (SockAddrInet p a) (SockAddrInet _ b) = a == b && matchport p
+ match (SockAddrInet6 p _ a _) (SockAddrInet6 _ _ b _) = a == b && matchport p
match _ _ = False
+
+ matchport p = case mp of
+ Nothing -> True
+ Just p' -> p == p'
+
Note that, since the interfaces of curl and youtube-dl do not allow
these IP address restrictions to be enforced, curl and youtube-dl will
never be used unless annex.security.allowed-ip-addresses=all.
+
+ To allow accessing local or private IP addresses on only specific ports,
+ use the syntax "[addr]:port". For example,
+ "[127.0.0.1]:80 [127.0.0.1]:443 [::1]:80 [::1]:443" allows
+ localhost on the http ports only.
* `annex.security.allowed-http-addresses`
date="2020-02-25T18:32:02Z"
content="""
As to ports, it seems reasonable to support eg
-security.allowed-ip-addresses=127.0.0.1:80 to make sure that the massive
+security.allowed-ip-addresses=[127.0.0.1]:80 to make sure that the massive
electron app I have running on some random other port doesn't get abused
to exfiltrate the contents of my $HOME. As a non-random example. :)
"""]]
--- /dev/null
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 3"""
+ date="2020-02-25T19:30:35Z"
+ content="""
+Implemented specifying allowed ports.
+"""]]