github.com/mysteriumnetwork/node@v0.0.0-20240516044423-365054f76801/services/openvpn/service/auth_handler.go (about) 1 /* 2 * Copyright (C) 2018 The "MysteriumNetwork/node" Authors. 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 3 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 package service 19 20 import ( 21 "github.com/mysteriumnetwork/go-openvpn/openvpn/middlewares/server" 22 "github.com/mysteriumnetwork/go-openvpn/openvpn/middlewares/server/credentials" 23 "github.com/mysteriumnetwork/node/identity" 24 "github.com/mysteriumnetwork/node/services/openvpn" 25 "github.com/mysteriumnetwork/node/session" 26 "github.com/rs/zerolog/log" 27 ) 28 29 // authHandler authorizes incoming clients by registering a callback to check auth primitives. 30 // username - provider's sessionId 31 // password - consumer's identity signature 32 type authHandler struct { 33 *credentials.Middleware 34 35 clientMap *clientMap 36 identityExtractor identity.Extractor 37 } 38 39 // newAuthHandler return authHandler instance 40 func newAuthHandler(clientMap *clientMap, extractor identity.Extractor) *authHandler { 41 ah := new(authHandler) 42 ah.Middleware = credentials.NewMiddleware(ah.validate) 43 ah.Middleware.ClientsSubscribe(ah.handleClientEvent) 44 ah.clientMap = clientMap 45 ah.identityExtractor = extractor 46 return ah 47 } 48 49 func (ah *authHandler) handleClientEvent(event server.ClientEvent) { 50 switch event.EventType { 51 case server.Connect: 52 ah.clientMap.Add(event.ClientID, session.ID(event.Env["username"])) 53 case server.Disconnect: 54 ah.clientMap.Remove(event.ClientID) 55 } 56 } 57 58 // handleAuthorisation provides glue code for openvpn management interface to validate incoming client login request, 59 // it expects session id as username, and session signature signed by client as password 60 func (ah *authHandler) validate(_ int, username, password string) (bool, error) { 61 sessionID := session.ID(username) 62 currentSession, currentSessionFound := ah.clientMap.GetSession(sessionID) 63 if !currentSessionFound { 64 log.Warn().Msgf("Possible break-in attempt. No established session exists: %s", sessionID) 65 return false, nil 66 } 67 68 signature := identity.SignatureBase64(password) 69 signerID, err := ah.identityExtractor.Extract([]byte(openvpn.AuthSignaturePrefix+username), signature) 70 if err != nil { 71 log.Warn().Err(err).Msgf("Possible break-in attempt. Invalid session %s signature", sessionID) 72 return false, nil 73 } 74 if signerID != currentSession.ConsumerID { 75 log.Warn().Msgf("Possible break-in attempt. Invalid session %s consumer %s", sessionID, signerID) 76 return false, nil 77 } 78 79 return true, nil 80 }