github.com/Consensys/quorum@v21.1.0+incompatible/rpc/endpoints.go (about)

     1  // Copyright 2018 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser 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  // The go-ethereum library 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 Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package rpc
    18  
    19  import (
    20  	"context"
    21  	"crypto/tls"
    22  	"fmt"
    23  	"net"
    24  
    25  	"github.com/ethereum/go-ethereum/log"
    26  	"github.com/ethereum/go-ethereum/plugin/security"
    27  )
    28  
    29  // StartHTTPEndpoint starts the HTTP RPC endpoint, configured with cors/vhosts/modules
    30  // Quorum: tlsConfigSource and authManager are introduced to secure the HTTP endpoint
    31  func StartHTTPEndpoint(endpoint string, apis []API, modules []string, cors []string, vhosts []string, timeouts HTTPTimeouts, tlsConfigSource security.TLSConfigurationSource, authManager security.AuthenticationManager) (net.Listener, *Server, bool, error) {
    32  	// Generate the whitelist based on the allowed modules
    33  	whitelist := make(map[string]bool)
    34  	for _, module := range modules {
    35  		whitelist[module] = true
    36  	}
    37  	// Register all the APIs exposed by the services
    38  	handler := NewProtectedServer(authManager)
    39  	for _, api := range apis {
    40  		if whitelist[api.Namespace] || (len(whitelist) == 0 && api.Public) {
    41  			if err := handler.RegisterName(api.Namespace, api.Service); err != nil {
    42  				return nil, nil, false, err
    43  			}
    44  			log.Debug("HTTP registered", "namespace", api.Namespace)
    45  		}
    46  	}
    47  	// All APIs registered, start the HTTP listener
    48  	var (
    49  		listener     net.Listener
    50  		err          error
    51  		isTlsEnabled bool
    52  	)
    53  	if isTlsEnabled, listener, err = startListener(endpoint, tlsConfigSource); err != nil {
    54  		return nil, nil, isTlsEnabled, err
    55  	}
    56  	go NewHTTPServer(cors, vhosts, timeouts, handler).Serve(listener)
    57  	return listener, handler, isTlsEnabled, err
    58  }
    59  
    60  // Quorum
    61  // Produce net.Listener instance with TLS support if tlsConfigSource provides the config
    62  func startListener(endpoint string, tlsConfigSource security.TLSConfigurationSource) (bool, net.Listener, error) {
    63  	var tlsConfig *tls.Config
    64  	var err error
    65  	var listener net.Listener
    66  	isTlsEnabled := true
    67  	if tlsConfigSource != nil {
    68  		if tlsConfig, err = tlsConfigSource.Get(context.Background()); err != nil {
    69  			isTlsEnabled = false
    70  		}
    71  	} else {
    72  		isTlsEnabled = false
    73  		err = fmt.Errorf("no TLSConfigurationSource found")
    74  	}
    75  	if isTlsEnabled {
    76  		if listener, err = tls.Listen("tcp", endpoint, tlsConfig); err != nil {
    77  			return isTlsEnabled, nil, err
    78  		}
    79  	} else {
    80  		log.Info("Security: TLS not enabled", "endpoint", endpoint, "reason", err)
    81  		if listener, err = net.Listen("tcp", endpoint); err != nil {
    82  			return isTlsEnabled, nil, err
    83  		}
    84  	}
    85  	return isTlsEnabled, listener, nil
    86  }
    87  
    88  // StartWSEndpoint starts a websocket endpoint
    89  // Quorum: tlsConfigSource and authManager are introduced to secure the WS endpoint
    90  func StartWSEndpoint(endpoint string, apis []API, modules []string, wsOrigins []string, exposeAll bool, tlsConfigSource security.TLSConfigurationSource, authManager security.AuthenticationManager) (net.Listener, *Server, bool, error) {
    91  
    92  	// Generate the whitelist based on the allowed modules
    93  	whitelist := make(map[string]bool)
    94  	for _, module := range modules {
    95  		whitelist[module] = true
    96  	}
    97  	// Register all the APIs exposed by the services
    98  	handler := NewProtectedServer(authManager)
    99  	for _, api := range apis {
   100  		if exposeAll || whitelist[api.Namespace] || (len(whitelist) == 0 && api.Public) {
   101  			if err := handler.RegisterName(api.Namespace, api.Service); err != nil {
   102  				return nil, nil, false, err
   103  			}
   104  			log.Debug("WebSocket registered", "service", api.Service, "namespace", api.Namespace)
   105  		}
   106  	}
   107  	// All APIs registered, start the HTTP listener
   108  	var (
   109  		listener     net.Listener
   110  		err          error
   111  		isTlsEnabled bool
   112  	)
   113  	if isTlsEnabled, listener, err = startListener(endpoint, tlsConfigSource); err != nil {
   114  		return nil, nil, isTlsEnabled, err
   115  	}
   116  	go NewWSServer(wsOrigins, handler).Serve(listener)
   117  	return listener, handler, isTlsEnabled, err
   118  
   119  }
   120  
   121  // StartIPCEndpoint starts an IPC endpoint.
   122  func StartIPCEndpoint(ipcEndpoint string, apis []API) (net.Listener, *Server, error) {
   123  	// Register all the APIs exposed by the services.
   124  	handler := NewServer()
   125  	for _, api := range apis {
   126  		if err := handler.RegisterName(api.Namespace, api.Service); err != nil {
   127  			return nil, nil, err
   128  		}
   129  		log.Debug("IPC registered", "namespace", api.Namespace)
   130  	}
   131  	// All APIs registered, start the IPC listener.
   132  	listener, err := ipcListen(ipcEndpoint)
   133  	if err != nil {
   134  		return nil, nil, err
   135  	}
   136  	go handler.ServeListener(listener)
   137  	return listener, handler, nil
   138  }