rpc: Should validate server versions. (#2775)

Fixes #2764
This commit is contained in:
Harshavardhana 2016-09-24 03:34:45 -07:00 committed by GitHub
parent 669783f875
commit 1c941fd787
5 changed files with 25 additions and 11 deletions

View File

@ -53,8 +53,8 @@ type RPCLoginArgs struct {
// with subsequent requests.
type RPCLoginReply struct {
Token string
ServerVersion string
Timestamp time.Time
ServerVersion string
}
// Validates if incoming token is valid.
@ -90,11 +90,12 @@ type authConfig struct {
// AuthRPCClient is a wrapper type for RPCClient which provides JWT based authentication across reconnects.
type AuthRPCClient struct {
config *authConfig
rpc *RPCClient // reconnect'able rpc client built on top of net/rpc Client
isLoggedIn bool // Indicates if the auth client has been logged in and token is valid.
token string // JWT based token
tstamp time.Time // Timestamp as received on Login RPC.
config *authConfig
rpc *RPCClient // reconnect'able rpc client built on top of net/rpc Client
isLoggedIn bool // Indicates if the auth client has been logged in and token is valid.
token string // JWT based token
tstamp time.Time // Timestamp as received on Login RPC.
serverVerison string // Server version exchanged by the RPC.
}
// newAuthClient - returns a jwt based authenticated (go) rpc client, which does automatic reconnect.
@ -129,9 +130,14 @@ func (authClient *AuthRPCClient) Login() error {
}, &reply); err != nil {
return err
}
// Validate if version do indeed match.
if reply.ServerVersion != Version {
return errServerVersionMismatch
}
// Set token, time stamp as received from a successful login call.
authClient.token = reply.Token
authClient.tstamp = reply.Timestamp
authClient.serverVerison = reply.ServerVersion
authClient.isLoggedIn = true
return nil
}

View File

@ -21,6 +21,9 @@ import "errors"
// errServerNotInitialized - server not initialized.
var errServerNotInitialized = errors.New("Server not initialized, please try again.")
// errServerVersionMismatch - server versions do not match.
var errServerVersionMismatch = errors.New("Server versions do not match.")
/// Auth operations
// Login - login handler.

View File

@ -154,6 +154,7 @@ func (l *lockServer) LoginHandler(args *RPCLoginArgs, reply *RPCLoginReply) erro
}
reply.Token = token
reply.Timestamp = l.timestamp
reply.ServerVersion = Version
return nil
}

View File

@ -50,7 +50,6 @@ func initDsyncNodes(disks []string, port int) error {
path: pathutil.Join(lockRPCPath, disk[idx+1:]),
loginMethod: "Dsync.LoginHandler",
}))
if isLocalStorage(disk) && myNode == -1 {
myNode = len(clnts) - 1
}

View File

@ -22,6 +22,7 @@ import (
"net/rpc"
"path"
"strings"
"time"
router "github.com/gorilla/mux"
"github.com/minio/minio/pkg/disk"
@ -30,8 +31,9 @@ import (
// Storage server implements rpc primitives to facilitate exporting a
// disk over a network.
type storageServer struct {
storage StorageAPI
path string
storage StorageAPI
path string
timestamp time.Time
}
/// Auth operations
@ -50,6 +52,7 @@ func (s *storageServer) LoginHandler(args *RPCLoginArgs, reply *RPCLoginReply) e
return err
}
reply.Token = token
reply.Timestamp = s.timestamp
reply.ServerVersion = Version
return nil
}
@ -213,6 +216,7 @@ func newRPCServer(serverConfig serverCmdConfig) (servers []*storageServer, err e
for _, ignoredExport := range ignoredExports {
skipDisks[ignoredExport] = true
}
t := time.Now().UTC()
for _, export := range exports {
if skipDisks[export] {
continue
@ -231,8 +235,9 @@ func newRPCServer(serverConfig serverCmdConfig) (servers []*storageServer, err e
export = export[idx+1:]
}
servers = append(servers, &storageServer{
storage: storage,
path: export,
storage: storage,
path: export,
timestamp: t,
})
}
}