implement p2p command
This commit is contained in:
parent
ac0cb5c2cc
commit
bfc8305814
10 changed files with 110 additions and 33 deletions
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
61
Command/P2P.hs
Normal file
61
Command/P2P.hs
Normal file
|
@ -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
|
||||
|
|
@ -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)
|
||||
|
||||
|
|
37
P2P/Auth.hs
37
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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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/`
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue