Add a --protocol-min-version option to router
To allow users to forgo compatibility with Weave Net 1.0 in order to avoid #912, by setting --protocol-min-version=2. Defaults to --protocol-min-version=1, i.e. compatible but vulnerable.
This commit is contained in:
1 parent
882f14d50c
commit
14d346db8b
5 files changed
+77
-65
No files matched your search
+25
-18
@@ -32,28 +32,30 @@ func main() {
|
||||
runtime.GOMAXPROCS(procs)
|
||||
|
||||
var (
|
||||
config weave.Config
|
||||
justVersion bool
|
||||
ifaceName string
|
||||
routerName string
|
||||
nickName string
|
||||
password string
|
||||
wait int
|
||||
pktdebug bool
|
||||
logLevel string
|
||||
prof string
|
||||
bufSzMB int
|
||||
noDiscovery bool
|
||||
httpAddr string
|
||||
iprangeCIDR string
|
||||
ipsubnetCIDR string
|
||||
peerCount int
|
||||
apiPath string
|
||||
peers []string
|
||||
config weave.Config
|
||||
justVersion bool
|
||||
protocolMinVersion int
|
||||
ifaceName string
|
||||
routerName string
|
||||
nickName string
|
||||
password string
|
||||
wait int
|
||||
pktdebug bool
|
||||
logLevel string
|
||||
prof string
|
||||
bufSzMB int
|
||||
noDiscovery bool
|
||||
httpAddr string
|
||||
iprangeCIDR string
|
||||
ipsubnetCIDR string
|
||||
peerCount int
|
||||
apiPath string
|
||||
peers []string
|
||||
)
|
||||
|
||||
mflag.BoolVar(&justVersion, []string{"#version", "-version"}, false, "print version and exit")
|
||||
mflag.IntVar(&config.Port, []string{"#port", "-port"}, weave.Port, "router port")
|
||||
mflag.IntVar(&protocolMinVersion, []string{"-min-protocol-version"}, weave.ProtocolMinVersion, "minimum weave protocol version")
|
||||
mflag.StringVar(&ifaceName, []string{"#iface", "-iface"}, "", "name of interface to capture/inject from (disabled if blank)")
|
||||
mflag.StringVar(&routerName, []string{"#name", "-name"}, "", "name of router (defaults to MAC of interface)")
|
||||
mflag.StringVar(&nickName, []string{"#nickname", "-nickname"}, "", "nickname of peer (defaults to hostname)")
|
||||
@@ -82,6 +84,11 @@ func main() {
|
||||
Log.Println("Command line options:", options())
|
||||
Log.Println("Command line peers:", peers)
|
||||
|
||||
if protocolMinVersion < weave.ProtocolMinVersion || protocolMinVersion > weave.ProtocolMaxVersion {
|
||||
Log.Fatalf("--min-protocol-version must be in range [%d,%d]", weave.ProtocolMinVersion, weave.ProtocolMaxVersion)
|
||||
}
|
||||
config.ProtocolMinVersion = byte(protocolMinVersion)
|
||||
|
||||
var err error
|
||||
|
||||
if ifaceName != "" {
|
||||
|
||||
@@ -285,10 +285,12 @@ func (conn *LocalConnection) run(actionChan <-chan ConnectionAction, finished ch
|
||||
|
||||
conn.TCPConn.SetLinger(0)
|
||||
intro, err := ProtocolIntroParams{
|
||||
Features: conn.makeFeatures(),
|
||||
Conn: conn.TCPConn,
|
||||
Password: conn.Router.Password,
|
||||
Outbound: conn.outbound,
|
||||
MinVersion: conn.Router.ProtocolMinVersion,
|
||||
MaxVersion: ProtocolMaxVersion,
|
||||
Features: conn.makeFeatures(),
|
||||
Conn: conn.TCPConn,
|
||||
Password: conn.Router.Password,
|
||||
Outbound: conn.outbound,
|
||||
}.DoIntro()
|
||||
if err != nil {
|
||||
return
|
||||
|
||||
+22
-24
@@ -10,9 +10,9 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
Protocol = "weave"
|
||||
ProtocolMinVersion byte = 1
|
||||
ProtocolVersion byte = 2
|
||||
Protocol = "weave"
|
||||
ProtocolMinVersion = 1
|
||||
ProtocolMaxVersion = 2
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -48,10 +48,12 @@ type ProtocolIntroConn interface {
|
||||
}
|
||||
|
||||
type ProtocolIntroParams struct {
|
||||
Features map[string]string
|
||||
Conn ProtocolIntroConn
|
||||
Password []byte
|
||||
Outbound bool
|
||||
MinVersion byte
|
||||
MaxVersion byte
|
||||
Features map[string]string
|
||||
Conn ProtocolIntroConn
|
||||
Password []byte
|
||||
Outbound bool
|
||||
}
|
||||
|
||||
type ProtocolIntroResults struct {
|
||||
@@ -63,15 +65,11 @@ type ProtocolIntroResults struct {
|
||||
}
|
||||
|
||||
func (params ProtocolIntroParams) DoIntro() (res ProtocolIntroResults, err error) {
|
||||
return params.doIntro(ProtocolVersion)
|
||||
}
|
||||
|
||||
func (params ProtocolIntroParams) doIntro(maxVersion byte) (res ProtocolIntroResults, err error) {
|
||||
if err = params.Conn.SetDeadline(time.Now().Add(HeaderTimeout)); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if res.Version, err = params.exchangeProtocolHeader(maxVersion); err != nil {
|
||||
if res.Version, err = params.exchangeProtocolHeader(); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -101,12 +99,12 @@ func (params ProtocolIntroParams) doIntro(maxVersion byte) (res ProtocolIntroRes
|
||||
return
|
||||
}
|
||||
|
||||
func (params ProtocolIntroParams) exchangeProtocolHeader(maxVersion byte) (byte, error) {
|
||||
func (params ProtocolIntroParams) exchangeProtocolHeader() (byte, error) {
|
||||
// Write in a separate goroutine to avoid the possibility of
|
||||
// deadlock. The result channel is of size 1 so that the
|
||||
// goroutine does not linger even if we encounter an error on
|
||||
// the read side.
|
||||
sendHeader := append(ProtocolBytes, ProtocolMinVersion, maxVersion)
|
||||
sendHeader := append(ProtocolBytes, params.MinVersion, params.MaxVersion)
|
||||
writeDone := make(chan error, 1)
|
||||
go func() {
|
||||
_, err := params.Conn.Write(sendHeader)
|
||||
@@ -127,27 +125,27 @@ func (params ProtocolIntroParams) exchangeProtocolHeader(maxVersion byte) (byte,
|
||||
|
||||
theirMinVersion := header[len(ProtocolBytes)]
|
||||
minVersion := theirMinVersion
|
||||
if ProtocolMinVersion > minVersion {
|
||||
minVersion = ProtocolMinVersion
|
||||
if params.MinVersion > minVersion {
|
||||
minVersion = params.MinVersion
|
||||
}
|
||||
|
||||
theirVersion := header[len(ProtocolBytes)+1]
|
||||
version := theirVersion
|
||||
if version > maxVersion {
|
||||
version = maxVersion
|
||||
theirMaxVersion := header[len(ProtocolBytes)+1]
|
||||
maxVersion := theirMaxVersion
|
||||
if maxVersion > params.MaxVersion {
|
||||
maxVersion = params.MaxVersion
|
||||
}
|
||||
|
||||
if minVersion > version {
|
||||
if minVersion > maxVersion {
|
||||
return 0, fmt.Errorf("remote version range [%d,%d] is incompatible with ours [%d,%d]",
|
||||
theirMinVersion, theirVersion,
|
||||
ProtocolMinVersion, maxVersion)
|
||||
theirMinVersion, theirMaxVersion,
|
||||
params.MinVersion, params.MaxVersion)
|
||||
}
|
||||
|
||||
if err := <-writeDone; err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return version, nil
|
||||
return maxVersion, nil
|
||||
}
|
||||
|
||||
// The V1 procotol consists of the protocol identification/version
|
||||
|
||||
+16
-12
@@ -33,10 +33,10 @@ func connPair() (ProtocolIntroConn, ProtocolIntroConn) {
|
||||
return &a, &b
|
||||
}
|
||||
|
||||
func doIntro(t *testing.T, ver byte, params ProtocolIntroParams) <-chan ProtocolIntroResults {
|
||||
func doIntro(t *testing.T, params ProtocolIntroParams) <-chan ProtocolIntroResults {
|
||||
ch := make(chan ProtocolIntroResults, 1)
|
||||
go func() {
|
||||
res, err := params.doIntro(ver)
|
||||
res, err := params.DoIntro()
|
||||
require.Nil(t, err)
|
||||
ch <- res
|
||||
}()
|
||||
@@ -45,17 +45,21 @@ func doIntro(t *testing.T, ver byte, params ProtocolIntroParams) <-chan Protocol
|
||||
|
||||
func doProtocolIntro(t *testing.T, aver, bver byte, password []byte) byte {
|
||||
aconn, bconn := connPair()
|
||||
aresch := doIntro(t, aver, ProtocolIntroParams{
|
||||
Features: map[string]string{"Name": "A"},
|
||||
Conn: aconn,
|
||||
Outbound: true,
|
||||
Password: password,
|
||||
aresch := doIntro(t, ProtocolIntroParams{
|
||||
MinVersion: ProtocolMinVersion,
|
||||
MaxVersion: aver,
|
||||
Features: map[string]string{"Name": "A"},
|
||||
Conn: aconn,
|
||||
Outbound: true,
|
||||
Password: password,
|
||||
})
|
||||
bresch := doIntro(t, bver, ProtocolIntroParams{
|
||||
Features: map[string]string{"Name": "B"},
|
||||
Conn: bconn,
|
||||
Outbound: false,
|
||||
Password: password,
|
||||
bresch := doIntro(t, ProtocolIntroParams{
|
||||
MinVersion: ProtocolMinVersion,
|
||||
MaxVersion: bver,
|
||||
Features: map[string]string{"Name": "B"},
|
||||
Conn: bconn,
|
||||
Outbound: false,
|
||||
Password: password,
|
||||
})
|
||||
ares := <-aresch
|
||||
bres := <-bresch
|
||||
|
||||
+8
-7
@@ -28,13 +28,14 @@ const (
|
||||
type LogFrameFunc func(string, []byte, *EthernetDecoder)
|
||||
|
||||
type Config struct {
|
||||
Port int
|
||||
Iface *net.Interface
|
||||
Password []byte
|
||||
ConnLimit int
|
||||
PeerDiscovery bool
|
||||
BufSz int
|
||||
LogFrame LogFrameFunc
|
||||
Port int
|
||||
ProtocolMinVersion byte
|
||||
Iface *net.Interface
|
||||
Password []byte
|
||||
ConnLimit int
|
||||
PeerDiscovery bool
|
||||
BufSz int
|
||||
LogFrame LogFrameFunc
|
||||
}
|
||||
|
||||
type Router struct {
|
||||
|
||||
Reference in new issue
Block a user