diff options
author | Joey Hess <joeyh@joeyh.name> | 2016-11-30 14:35:24 -0400 |
---|---|---|
committer | Joey Hess <joeyh@joeyh.name> | 2016-11-30 14:35:24 -0400 |
commit | 66b3af4aa5c3bbb53fc27b25303c4e69364930f5 (patch) | |
tree | acb9491353a5c5f8a143b29e8aff92533b8c359d | |
parent | ef6cd4fe3a5bf0163ae3e50ac6248dc11d8a7bcf (diff) |
implement p2p command
-rw-r--r-- | Annex/SpecialRemote.hs | 3 | ||||
-rw-r--r-- | CHANGELOG | 1 | ||||
-rw-r--r-- | CmdLine/GitAnnex.hs | 2 | ||||
-rw-r--r-- | Command/EnableRemote.hs | 7 | ||||
-rw-r--r-- | Command/P2P.hs | 61 | ||||
-rw-r--r-- | P2P/Address.hs | 5 | ||||
-rw-r--r-- | P2P/Auth.hs | 37 | ||||
-rw-r--r-- | doc/git-annex-p2p.mdwn | 8 | ||||
-rw-r--r-- | doc/tips/peer_to_peer_network_with_tor.mdwn | 16 | ||||
-rw-r--r-- | git-annex.cabal | 3 |
10 files changed, 110 insertions, 33 deletions
diff --git a/Annex/SpecialRemote.hs b/Annex/SpecialRemote.hs index 02799db85..0fd24f023 100644 --- a/Annex/SpecialRemote.hs +++ b/Annex/SpecialRemote.hs @@ -13,12 +13,11 @@ import Types.Remote (RemoteConfig, RemoteConfigKey, typename, setup) import Logs.Remote import Logs.Trust import qualified Git.Config +import Git.Types (RemoteName) import qualified Data.Map as M import Data.Ord -type RemoteName = String - {- See if there's an existing special remote with this name. - - Prefer remotes that are not dead when a name appears multiple times. -} @@ -1,6 +1,7 @@ git-annex (6.20161119) UNRELEASED; urgency=medium * enable-tor: New command, enables tor hidden service for P2P syncing. + * p2p: New command, allows linking repositories using a P2P network. * remotedaemon: Serve tor hidden service. * Added git-remote-tor-annex, which allows git pull and push to the tor hidden service. diff --git a/CmdLine/GitAnnex.hs b/CmdLine/GitAnnex.hs index 0fa14c98b..a12366b74 100644 --- a/CmdLine/GitAnnex.hs +++ b/CmdLine/GitAnnex.hs @@ -96,6 +96,7 @@ import qualified Command.Direct import qualified Command.Indirect import qualified Command.Upgrade import qualified Command.Forget +import qualified Command.P2P import qualified Command.Proxy import qualified Command.DiffDriver import qualified Command.Smudge @@ -204,6 +205,7 @@ cmds testoptparser testrunner = , Command.Indirect.cmd , Command.Upgrade.cmd , Command.Forget.cmd + , Command.P2P.cmd , Command.Proxy.cmd , Command.DiffDriver.cmd , Command.Smudge.cmd diff --git a/Command/EnableRemote.hs b/Command/EnableRemote.hs index e1af8bb7a..61cd543e6 100644 --- a/Command/EnableRemote.hs +++ b/Command/EnableRemote.hs @@ -12,6 +12,7 @@ import qualified Annex import qualified Logs.Remote import qualified Types.Remote as R import qualified Git +import qualified Git.Types as Git import qualified Annex.SpecialRemote import qualified Remote import qualified Types.Remote as Remote @@ -40,9 +41,7 @@ start (name:rest) = go =<< filter matchingname <$> Annex.fromRepo Git.remotes =<< Annex.SpecialRemote.findExisting name go (r:_) = startNormalRemote name r -type RemoteName = String - -startNormalRemote :: RemoteName -> Git.Repo -> CommandStart +startNormalRemote :: Git.RemoteName -> Git.Repo -> CommandStart startNormalRemote name r = do showStart "enableremote" name next $ next $ do @@ -51,7 +50,7 @@ startNormalRemote name r = do u <- getRepoUUID r' return $ u /= NoUUID -startSpecialRemote :: RemoteName -> Remote.RemoteConfig -> Maybe (UUID, Remote.RemoteConfig) -> CommandStart +startSpecialRemote :: Git.RemoteName -> Remote.RemoteConfig -> Maybe (UUID, Remote.RemoteConfig) -> CommandStart startSpecialRemote name config Nothing = do m <- Annex.SpecialRemote.specialRemoteMap confm <- Logs.Remote.readRemoteLog diff --git a/Command/P2P.hs b/Command/P2P.hs new file mode 100644 index 000000000..ec6e4be96 --- /dev/null +++ b/Command/P2P.hs @@ -0,0 +1,61 @@ +{- git-annex command + - + - Copyright 2016 Joey Hess <id@joeyh.name> + - + - Licensed under the GNU GPL version 3 or higher. + -} + +module Command.P2P where + +import Command +import Git.Types +import P2P.Address +import P2P.Auth +import Utility.AuthToken + +cmd :: Command +cmd = command "p2p" SectionSetup + "configure peer-2-peer links between repositories" + paramNothing (seek <$$> optParser) + +data P2POpts + = GenAddresses + | LinkRemote P2PAddressAuth RemoteName + +optParser :: CmdParamsDesc -> Parser P2POpts +optParser _ = genaddresses <|> linkremote + where + genaddresses = flag' GenAddresses + ( long "gen-addresses" + <> help "generate addresses that allow accessing this repository over P2P networks" + ) + linkremote = LinkRemote + <$> option readaddr + ( long "link" + <> metavar paramAddress + <> help "address of the peer to link with" + ) + <*> strOption + ( long "named" + <> metavar paramRemote + <> help "specify name to use for git remote" + ) + readaddr = eitherReader $ maybe (Left "address parse error") Right + . unformatP2PAddress + +seek :: P2POpts -> CommandSeek +seek GenAddresses = do + addrs <- loadP2PAddresses + if null addrs + then giveup "No P2P networks are currrently available." + else do + authtoken <- liftIO $ genAuthToken 128 + storeP2PAuthToken authtoken + -- Only addresses are output to stdout, to allow + -- scripting. + earlyWarning "These addresses allow access to this git-annex repository. Only share them with people you trust with that access, using trusted communication channels!" + liftIO $ putStr $ unlines $ + map formatP2PAddress $ + map (`P2PAddressAuth` authtoken) addrs +seek (LinkRemote addr name) = do + diff --git a/P2P/Address.hs b/P2P/Address.hs index 862f06a9c..19ff82a89 100644 --- a/P2P/Address.hs +++ b/P2P/Address.hs @@ -23,7 +23,10 @@ import qualified Data.Text as T data P2PAddress = TorAnnex OnionAddress OnionPort deriving (Eq, Show) --- | A P2P address, with an AuthToken +-- | A P2P address, with an AuthToken. +-- +-- This is enough information to connect to the peer, and authenticate with +-- it. data P2PAddressAuth = P2PAddressAuth P2PAddress AuthToken deriving (Eq, Show) diff --git a/P2P/Auth.hs b/P2P/Auth.hs index 5c3feb713..2482c1dc0 100644 --- a/P2P/Auth.hs +++ b/P2P/Auth.hs @@ -1,4 +1,4 @@ -{- P2P protocol, authorization +{- P2P authtokens - - Copyright 2016 Joey Hess <id@joeyh.name> - @@ -7,24 +7,29 @@ module P2P.Auth where -import Common +import Annex.Common +import Creds import Utility.AuthToken import qualified Data.Text as T --- Use .git/annex/creds/p2p to hold AuthTokens of authorized peers. -getAuthTokens :: Annex AllowedAuthTokens -getAuthTokens = allowedAuthTokens <$> getAuthTokens' +-- | Load authtokens that are accepted by this repository. +loadP2PAuthTokens :: Annex AllowedAuthTokens +loadP2PAuthTokens = allowedAuthTokens <$> loadP2PAuthTokens' -getAuthTokens' :: Annex [AuthTokens] -getAuthTokens' = mapMaybe toAuthToken - . map T.pack - . lines - . fromMaybe [] - <$> readCacheCreds "tor" +loadP2PAuthTokens' :: Annex [AuthToken] +loadP2PAuthTokens' = mapMaybe toAuthToken + . map T.pack + . lines + . fromMaybe [] + <$> readCacheCreds p2pAuthCredsFile -addAuthToken :: AuthToken -> Annex () -addAuthToken t = do - ts <- getAuthTokens' - let d = unlines $ map (T.unpack . fromAuthToken) (t:ts) - writeCacheCreds d "tor" +storeP2PAuthToken :: AuthToken -> Annex () +storeP2PAuthToken t = do + ts <- loadP2PAuthTokens' + unless (t `elem` ts) $ do + let d = unlines $ map (T.unpack . fromAuthToken) (t:ts) + writeCacheCreds d p2pAuthCredsFile + +p2pAuthCredsFile :: FilePath +p2pAuthCredsFile = "p2pauth" diff --git a/doc/git-annex-p2p.mdwn b/doc/git-annex-p2p.mdwn index 8e06cc47c..049f90014 100644 --- a/doc/git-annex-p2p.mdwn +++ b/doc/git-annex-p2p.mdwn @@ -11,14 +11,18 @@ git annex p2p [options] This command can be used to link git-annex repositories over peer-2-peer networks. +Currently, the only P2P network supported by git-annex is Tor hidden +services. + # OPTIONS * `--gen-address` Generates addresses that can be used to access this git-annex repository - over a P2P network. The address or addresses is output to stdout. + over the available P2P networks. The address or addresses is output to + stdout. -* `--link-remote remotename address` +* `--link address --named remotename` Sets up a git remote with the specified remotename that is accessed over a P2P network. The address is one generated in the remote repository using diff --git a/doc/tips/peer_to_peer_network_with_tor.mdwn b/doc/tips/peer_to_peer_network_with_tor.mdwn index 94470b96a..de018e3ce 100644 --- a/doc/tips/peer_to_peer_network_with_tor.mdwn +++ b/doc/tips/peer_to_peer_network_with_tor.mdwn @@ -44,7 +44,7 @@ repository: Now, tell the new peer about the address of the first peer: - git annex p2p --link-remote peer1 tor-annnex::eeaytkuhaupbarfi.onion:4412:7f53c5b65b8957ef626fd461ceaae8056e3dbc459ae715e4 + git annex p2p --link tor-annnex::eeaytkuhaupbarfi.onion:4412:7f53c5b65b8957ef626fd461ceaae8056e3dbc459ae715e4 --named peer1 (Of course, you should paste in the address you generated earlier, not the example one shown above.) @@ -56,8 +56,8 @@ You can run any commands you normally would to sync with that remote: git annex sync --content peer1 You can also generate an address for this new peer, by running `git annex -p2p --gen-address`, and add that address to other peers using `git annex -p2p --link-remote`. It's often useful to link peers up in both directions, +p2p --gen-address`, and link other peers to that address using `git annex +p2p --link`. It's often useful to link peers up in both directions, so peer1 is a remote of peer2 and peer2 is a remote of peer1. Any number of peers can be connected this way, within reason. @@ -88,14 +88,14 @@ You can `git pull`, push, etc with those onion addresses: git remote add peer1 tor-annnex::eeaytkuhaupbarfi.onion:4412 Onion addresses are semi-public. When you add a remote, they appear in your -`.git/config` file. So, there's a second level of authentication that -git-annex uses to make sure that only people you want to can access your -repository over Tor. That takes the form of a long string of numbers and -letters, like "7f53c5b65b8957ef626fd461ceaae8056e3dbc459ae715e4". +`.git/config` file. For security, there's a second level of authentication +that git-annex uses to make sure that only people you want to can access +your repository over Tor. That takes the form of a long string of numbers +and letters, like "7f53c5b65b8957ef626fd461ceaae8056e3dbc459ae715e4". The addresses generated by `git annex peer --gen-address` combine the onion address with the authentication data. -When you run `git annex peer --link-remote`, it sets up a git remote using +When you run `git annex peer --link`, it sets up a git remote using the onion address, and it stashes the authentication data away in a file in `.git/annex/creds/` diff --git a/git-annex.cabal b/git-annex.cabal index 5a446ac7a..6991d2a04 100644 --- a/git-annex.cabal +++ b/git-annex.cabal @@ -91,6 +91,7 @@ Extra-Source-Files: doc/git-annex-mirror.mdwn doc/git-annex-move.mdwn doc/git-annex-numcopies.mdwn + doc/git-annex-p2p.mdwn doc/git-annex-pre-commit.mdwn doc/git-annex-preferred-content.mdwn doc/git-annex-proxy.mdwn @@ -727,6 +728,7 @@ Executable git-annex Command.DropKey Command.DropUnused Command.EnableRemote + Command.EnableTor Command.ExamineKey Command.Expire Command.Find @@ -762,6 +764,7 @@ Executable git-annex Command.Move Command.NotifyChanges Command.NumCopies + Command.P2P Command.PreCommit Command.Proxy Command.ReKey |