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.Remote
|
||||||
import Logs.Trust
|
import Logs.Trust
|
||||||
import qualified Git.Config
|
import qualified Git.Config
|
||||||
|
import Git.Types (RemoteName)
|
||||||
|
|
||||||
import qualified Data.Map as M
|
import qualified Data.Map as M
|
||||||
import Data.Ord
|
import Data.Ord
|
||||||
|
|
||||||
type RemoteName = String
|
|
||||||
|
|
||||||
{- See if there's an existing special remote with this name.
|
{- See if there's an existing special remote with this name.
|
||||||
-
|
-
|
||||||
- Prefer remotes that are not dead when a name appears multiple times. -}
|
- Prefer remotes that are not dead when a name appears multiple times. -}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
git-annex (6.20161119) UNRELEASED; urgency=medium
|
git-annex (6.20161119) UNRELEASED; urgency=medium
|
||||||
|
|
||||||
* enable-tor: New command, enables tor hidden service for P2P syncing.
|
* 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.
|
* remotedaemon: Serve tor hidden service.
|
||||||
* Added git-remote-tor-annex, which allows git pull and push to the tor
|
* Added git-remote-tor-annex, which allows git pull and push to the tor
|
||||||
hidden service.
|
hidden service.
|
||||||
|
|
|
@ -96,6 +96,7 @@ import qualified Command.Direct
|
||||||
import qualified Command.Indirect
|
import qualified Command.Indirect
|
||||||
import qualified Command.Upgrade
|
import qualified Command.Upgrade
|
||||||
import qualified Command.Forget
|
import qualified Command.Forget
|
||||||
|
import qualified Command.P2P
|
||||||
import qualified Command.Proxy
|
import qualified Command.Proxy
|
||||||
import qualified Command.DiffDriver
|
import qualified Command.DiffDriver
|
||||||
import qualified Command.Smudge
|
import qualified Command.Smudge
|
||||||
|
@ -204,6 +205,7 @@ cmds testoptparser testrunner =
|
||||||
, Command.Indirect.cmd
|
, Command.Indirect.cmd
|
||||||
, Command.Upgrade.cmd
|
, Command.Upgrade.cmd
|
||||||
, Command.Forget.cmd
|
, Command.Forget.cmd
|
||||||
|
, Command.P2P.cmd
|
||||||
, Command.Proxy.cmd
|
, Command.Proxy.cmd
|
||||||
, Command.DiffDriver.cmd
|
, Command.DiffDriver.cmd
|
||||||
, Command.Smudge.cmd
|
, Command.Smudge.cmd
|
||||||
|
|
|
@ -12,6 +12,7 @@ import qualified Annex
|
||||||
import qualified Logs.Remote
|
import qualified Logs.Remote
|
||||||
import qualified Types.Remote as R
|
import qualified Types.Remote as R
|
||||||
import qualified Git
|
import qualified Git
|
||||||
|
import qualified Git.Types as Git
|
||||||
import qualified Annex.SpecialRemote
|
import qualified Annex.SpecialRemote
|
||||||
import qualified Remote
|
import qualified Remote
|
||||||
import qualified Types.Remote as 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
|
=<< Annex.SpecialRemote.findExisting name
|
||||||
go (r:_) = startNormalRemote name r
|
go (r:_) = startNormalRemote name r
|
||||||
|
|
||||||
type RemoteName = String
|
startNormalRemote :: Git.RemoteName -> Git.Repo -> CommandStart
|
||||||
|
|
||||||
startNormalRemote :: RemoteName -> Git.Repo -> CommandStart
|
|
||||||
startNormalRemote name r = do
|
startNormalRemote name r = do
|
||||||
showStart "enableremote" name
|
showStart "enableremote" name
|
||||||
next $ next $ do
|
next $ next $ do
|
||||||
|
@ -51,7 +50,7 @@ startNormalRemote name r = do
|
||||||
u <- getRepoUUID r'
|
u <- getRepoUUID r'
|
||||||
return $ u /= NoUUID
|
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
|
startSpecialRemote name config Nothing = do
|
||||||
m <- Annex.SpecialRemote.specialRemoteMap
|
m <- Annex.SpecialRemote.specialRemoteMap
|
||||||
confm <- Logs.Remote.readRemoteLog
|
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
|
data P2PAddress = TorAnnex OnionAddress OnionPort
|
||||||
deriving (Eq, Show)
|
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
|
data P2PAddressAuth = P2PAddressAuth P2PAddress AuthToken
|
||||||
deriving (Eq, Show)
|
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>
|
- Copyright 2016 Joey Hess <id@joeyh.name>
|
||||||
-
|
-
|
||||||
|
@ -7,24 +7,29 @@
|
||||||
|
|
||||||
module P2P.Auth where
|
module P2P.Auth where
|
||||||
|
|
||||||
import Common
|
import Annex.Common
|
||||||
|
import Creds
|
||||||
import Utility.AuthToken
|
import Utility.AuthToken
|
||||||
|
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
|
|
||||||
-- Use .git/annex/creds/p2p to hold AuthTokens of authorized peers.
|
-- | Load authtokens that are accepted by this repository.
|
||||||
getAuthTokens :: Annex AllowedAuthTokens
|
loadP2PAuthTokens :: Annex AllowedAuthTokens
|
||||||
getAuthTokens = allowedAuthTokens <$> getAuthTokens'
|
loadP2PAuthTokens = allowedAuthTokens <$> loadP2PAuthTokens'
|
||||||
|
|
||||||
getAuthTokens' :: Annex [AuthTokens]
|
loadP2PAuthTokens' :: Annex [AuthToken]
|
||||||
getAuthTokens' = mapMaybe toAuthToken
|
loadP2PAuthTokens' = mapMaybe toAuthToken
|
||||||
. map T.pack
|
. map T.pack
|
||||||
. lines
|
. lines
|
||||||
. fromMaybe []
|
. fromMaybe []
|
||||||
<$> readCacheCreds "tor"
|
<$> readCacheCreds p2pAuthCredsFile
|
||||||
|
|
||||||
addAuthToken :: AuthToken -> Annex ()
|
storeP2PAuthToken :: AuthToken -> Annex ()
|
||||||
addAuthToken t = do
|
storeP2PAuthToken t = do
|
||||||
ts <- getAuthTokens'
|
ts <- loadP2PAuthTokens'
|
||||||
let d = unlines $ map (T.unpack . fromAuthToken) (t:ts)
|
unless (t `elem` ts) $ do
|
||||||
writeCacheCreds d "tor"
|
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
|
This command can be used to link git-annex repositories over peer-2-peer
|
||||||
networks.
|
networks.
|
||||||
|
|
||||||
|
Currently, the only P2P network supported by git-annex is Tor hidden
|
||||||
|
services.
|
||||||
|
|
||||||
# OPTIONS
|
# OPTIONS
|
||||||
|
|
||||||
* `--gen-address`
|
* `--gen-address`
|
||||||
|
|
||||||
Generates addresses that can be used to access this git-annex repository
|
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
|
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
|
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:
|
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,
|
(Of course, you should paste in the address you generated earlier,
|
||||||
not the example one shown above.)
|
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
|
git annex sync --content peer1
|
||||||
|
|
||||||
You can also generate an address for this new peer, by running `git annex
|
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 --gen-address`, and link other peers to that address using `git annex
|
||||||
p2p --link-remote`. It's often useful to link peers up in both directions,
|
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.
|
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.
|
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
|
git remote add peer1 tor-annnex::eeaytkuhaupbarfi.onion:4412
|
||||||
|
|
||||||
Onion addresses are semi-public. When you add a remote, they appear in your
|
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/config` file. For security, there's a second level of authentication
|
||||||
git-annex uses to make sure that only people you want to can access your
|
that git-annex uses to make sure that only people you want to can access
|
||||||
repository over Tor. That takes the form of a long string of numbers and
|
your repository over Tor. That takes the form of a long string of numbers
|
||||||
letters, like "7f53c5b65b8957ef626fd461ceaae8056e3dbc459ae715e4".
|
and letters, like "7f53c5b65b8957ef626fd461ceaae8056e3dbc459ae715e4".
|
||||||
|
|
||||||
The addresses generated by `git annex peer --gen-address`
|
The addresses generated by `git annex peer --gen-address`
|
||||||
combine the onion address with the authentication data.
|
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
|
the onion address, and it stashes the authentication data away in a file in
|
||||||
`.git/annex/creds/`
|
`.git/annex/creds/`
|
||||||
|
|
|
@ -91,6 +91,7 @@ Extra-Source-Files:
|
||||||
doc/git-annex-mirror.mdwn
|
doc/git-annex-mirror.mdwn
|
||||||
doc/git-annex-move.mdwn
|
doc/git-annex-move.mdwn
|
||||||
doc/git-annex-numcopies.mdwn
|
doc/git-annex-numcopies.mdwn
|
||||||
|
doc/git-annex-p2p.mdwn
|
||||||
doc/git-annex-pre-commit.mdwn
|
doc/git-annex-pre-commit.mdwn
|
||||||
doc/git-annex-preferred-content.mdwn
|
doc/git-annex-preferred-content.mdwn
|
||||||
doc/git-annex-proxy.mdwn
|
doc/git-annex-proxy.mdwn
|
||||||
|
@ -727,6 +728,7 @@ Executable git-annex
|
||||||
Command.DropKey
|
Command.DropKey
|
||||||
Command.DropUnused
|
Command.DropUnused
|
||||||
Command.EnableRemote
|
Command.EnableRemote
|
||||||
|
Command.EnableTor
|
||||||
Command.ExamineKey
|
Command.ExamineKey
|
||||||
Command.Expire
|
Command.Expire
|
||||||
Command.Find
|
Command.Find
|
||||||
|
@ -762,6 +764,7 @@ Executable git-annex
|
||||||
Command.Move
|
Command.Move
|
||||||
Command.NotifyChanges
|
Command.NotifyChanges
|
||||||
Command.NumCopies
|
Command.NumCopies
|
||||||
|
Command.P2P
|
||||||
Command.PreCommit
|
Command.PreCommit
|
||||||
Command.Proxy
|
Command.Proxy
|
||||||
Command.ReKey
|
Command.ReKey
|
||||||
|
|
Loading…
Reference in a new issue