Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove openvpn session manager #377

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 1 addition & 2 deletions core/service/factory.go
Expand Up @@ -96,8 +96,7 @@ func NewManager(
serviceOptions.OpenvpnProtocol,
)

ovpnSessionManager := openvpn_session.NewManager(manager)
sessionValidator := openvpn_session.NewValidator(ovpnSessionManager, identity.NewExtractor())
sessionValidator := openvpn_session.NewValidator(manager, identity.NewExtractor())

return openvpn_node.NewServer(
nodeOptions.Openvpn.BinaryPath,
Expand Down
74 changes: 74 additions & 0 deletions services/openvpn/session/client_map.go
@@ -0,0 +1,74 @@
/*
* Copyright (C) 2018 The "MysteriumNetwork/node" Authors.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package session

import (
"errors"
"sync"

"github.com/mysteriumnetwork/node/session"
)

type clientMap struct {
sessionManager session.Manager
sessionClientIDs map[session.SessionID]int
sessionMapLock sync.Mutex
}

// FindClientSession returns OpenVPN session instance by given session id
func (cm *clientMap) FindClientSession(clientID int, id session.SessionID) (session.Session, bool, error) {
sessionInstance, sessionExist := cm.sessionManager.FindSession(id)
if !sessionExist {
return session.Session{}, false, errors.New("no underlying session exists, possible break-in attempt")
}

sessionClientID, clientIDExist := cm.sessionClientIDs[id]
if clientIDExist && clientID != sessionClientID {
return sessionInstance, false, errors.New("provided clientID does not mach active clientID")
}

return sessionInstance, clientIDExist, nil
}

// UpdateClientSession updates OpenVPN session with clientID, returns false on clientID conflict
func (cm *clientMap) UpdateClientSession(clientID int, id session.SessionID) bool {
cm.sessionMapLock.Lock()
defer cm.sessionMapLock.Unlock()

_, clientIDExist := cm.sessionClientIDs[id]
if !clientIDExist {
cm.sessionClientIDs[id] = clientID
}

return cm.sessionClientIDs[id] == clientID
}

// RemoveSession removes given session from underlying session managers
func (cm *clientMap) RemoveSession(id session.SessionID) error {
cm.sessionMapLock.Lock()
defer cm.sessionMapLock.Unlock()

_, clientIDExist := cm.sessionManager.FindSession(id)
if !clientIDExist {
return errors.New("no underlying session exists: " + string(id))
}

cm.sessionManager.RemoveSession(id)
delete(cm.sessionClientIDs, id)
return nil
}
84 changes: 0 additions & 84 deletions services/openvpn/session/manager.go

This file was deleted.

3 changes: 0 additions & 3 deletions services/openvpn/session/manager_auth_middleware_test.go
Expand Up @@ -22,8 +22,6 @@ import (

"github.com/mysteriumnetwork/node/openvpn/management"
"github.com/mysteriumnetwork/node/openvpn/middlewares/server/auth"
"github.com/mysteriumnetwork/node/session"

"github.com/stretchr/testify/assert"
)

Expand All @@ -32,7 +30,6 @@ type fakeAuthenticatorStub struct {
password string
called bool
authenticated bool
manager session.Manager
}

func (f *fakeAuthenticatorStub) fakeAuthenticator(clientID int, username, password string) (bool, error) {
Expand Down
24 changes: 11 additions & 13 deletions services/openvpn/session/validator.go
Expand Up @@ -18,7 +18,7 @@
package session

import (
"errors"
"sync"

"github.com/mysteriumnetwork/node/identity"
"github.com/mysteriumnetwork/node/session"
Expand All @@ -29,14 +29,18 @@ const SignaturePrefix = "MystVpnSessionId:"

// Validator structure that keeps attributes needed Validator operations
type Validator struct {
sessionManager *manager
clientMap *clientMap
identityExtractor identity.Extractor
}

// NewValidator return Validator instance
func NewValidator(m *manager, extractor identity.Extractor) *Validator {
func NewValidator(sessionManager session.Manager, extractor identity.Extractor) *Validator {
return &Validator{
sessionManager: m,
clientMap: &clientMap{
sessionManager: sessionManager,
sessionClientIDs: make(map[session.SessionID]int),
sessionMapLock: sync.Mutex{},
},
identityExtractor: extractor,
}
}
Expand All @@ -45,14 +49,14 @@ func NewValidator(m *manager, extractor identity.Extractor) *Validator {
// it expects session id as username, and session signature signed by client as password
func (v *Validator) Validate(clientID int, sessionString, signatureString string) (bool, error) {
sessionID := session.SessionID(sessionString)
currentSession, found, err := v.sessionManager.FindSession(clientID, sessionID)
currentSession, found, err := v.clientMap.FindClientSession(clientID, sessionID)

if err != nil {
return false, err
}

if !found {
v.sessionManager.UpdateSession(clientID, sessionID)
v.clientMap.UpdateClientSession(clientID, sessionID)
}

signature := identity.SignatureBase64(signatureString)
Expand All @@ -66,12 +70,6 @@ func (v *Validator) Validate(clientID int, sessionString, signatureString string
// Cleanup removes session from underlying session managers
func (v *Validator) Cleanup(sessionString string) error {
sessionID := session.SessionID(sessionString)
_, found := v.sessionManager.sessionManager.FindSession(sessionID)

if !found {
return errors.New("no underlying session exists: " + sessionString)
}

v.sessionManager.RemoveSession(sessionID)
return nil
return v.clientMap.RemoveSession(sessionID)
}
2 changes: 1 addition & 1 deletion services/openvpn/session/validator_mocks.go
Expand Up @@ -34,7 +34,7 @@ type MockIdentityExtractor struct {
OnExtractReturnError error
}

// MockSessionManager mocked session manager
// MockSessionManager mocked session clientMap
type MockSessionManager struct {
OnFindReturnSession session.Session
OnFindReturnSuccess bool
Expand Down
18 changes: 6 additions & 12 deletions services/openvpn/session/validator_test.go
Expand Up @@ -18,7 +18,6 @@
package session

import (
"sync"
"testing"

"github.com/mysteriumnetwork/node/identity"
Expand All @@ -40,22 +39,18 @@ var mockExtractor = &MockIdentityExtractor{
nil,
}

var fakeManager = NewManager(mockManager)

var mockValidator = NewValidator(fakeManager, mockExtractor)
var mockValidator = NewValidator(mockManager, mockExtractor)

func TestValidateReturnsFalseWhenNoSessionFound(t *testing.T) {
mockExtractor := &MockIdentityExtractor{}

sessionManager := session.NewManager(
mockedConfigProvider,
&session.GeneratorFake{
SessionIdMock: session.SessionID("mocked-id"),
},
)

manager := &manager{sessionManager, make(map[session.SessionID]int), sync.Mutex{}}
mockValidator := &Validator{manager, mockExtractor}
mockValidator := NewValidator(sessionManager, mockExtractor)
authenticated, err := mockValidator.Validate(1, "not important", "not important")

assert.Errorf(t, err, "no underlying session exists, possible break-in attempt")
Expand All @@ -68,8 +63,7 @@ func TestValidateReturnsFalseWhenSignatureIsInvalid(t *testing.T) {
nil,
}

mockValidator := &Validator{fakeManager, mockExtractor}

mockValidator := NewValidator(mockManager, mockExtractor)
authenticated, err := mockValidator.Validate(1, "not important", "not important")

assert.NoError(t, err)
Expand Down Expand Up @@ -102,7 +96,8 @@ func TestValidateReturnsTrueWhenSessionExistsAndSignatureIsValidAndClientIDMatch
func TestCleanupReturnsNoErrorIfSessionIsCleared(t *testing.T) {
mockValidator.Validate(1, "not important", "not important")
err := mockValidator.Cleanup("not important")
_, found, _ := fakeManager.FindSession(1, "not important")

_, found, _ := mockValidator.clientMap.FindClientSession(1, "not important")
assert.False(t, found)
assert.NoError(t, err)
}
Expand All @@ -113,9 +108,8 @@ func TestCleanupReturnsErrorIfSessionNotExists(t *testing.T) {
identity.FromAddress("deadbeef"),
nil,
}
fakeManager := NewManager(mockManager)
mockValidator := NewValidator(fakeManager, mockExtractor)

mockValidator := NewValidator(mockManager, mockExtractor)
err := mockValidator.Cleanup("nonexistent_session")

assert.Errorf(t, err, "no underlying session exists: nonexistent_session")
Expand Down