github.com/turingchain2020/turingchain@v1.1.21/rpc/server.go (about)

     1  // Copyright Turing Corp. 2018 All Rights Reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package rpc
     6  
     7  import (
     8  	"encoding/base64"
     9  	"fmt"
    10  	"net"
    11  	"net/http"
    12  	"net/rpc"
    13  	"strings"
    14  	"time"
    15  
    16  	"github.com/turingchain2020/turingchain/client"
    17  	"github.com/turingchain2020/turingchain/pluginmgr"
    18  	"github.com/turingchain2020/turingchain/queue"
    19  	"github.com/turingchain2020/turingchain/rpc/grpcclient"
    20  	_ "github.com/turingchain2020/turingchain/rpc/grpcclient" // register grpc multiple resolver
    21  	"github.com/turingchain2020/turingchain/types"
    22  	"golang.org/x/net/context"
    23  	"google.golang.org/grpc"
    24  	"google.golang.org/grpc/credentials"
    25  	_ "google.golang.org/grpc/encoding/gzip" // register gzip
    26  	"google.golang.org/grpc/keepalive"
    27  )
    28  
    29  var (
    30  	remoteIPWhitelist           = make(map[string]bool)
    31  	rpcCfg                      *types.RPC
    32  	jrpcFuncWhitelist           = make(map[string]bool)
    33  	grpcFuncWhitelist           = make(map[string]bool)
    34  	jrpcFuncBlacklist           = make(map[string]bool)
    35  	grpcFuncBlacklist           = make(map[string]bool)
    36  	rpcFilterPrintFuncBlacklist = make(map[string]bool)
    37  )
    38  
    39  // Turingchain  a channel client
    40  type Turingchain struct {
    41  	cli channelClient
    42  	//for communicate with main chain in parallel chain
    43  	mainGrpcCli types.TuringchainClient
    44  }
    45  
    46  // Grpc a channelClient
    47  type Grpc struct {
    48  	cli channelClient
    49  }
    50  
    51  // Grpcserver a object
    52  type Grpcserver struct {
    53  	grpc *Grpc
    54  	s    *grpc.Server
    55  	l    net.Listener
    56  }
    57  
    58  // NewGrpcServer new  GrpcServer object
    59  func NewGrpcServer() *Grpcserver {
    60  	return &Grpcserver{grpc: &Grpc{}}
    61  }
    62  
    63  // JSONRPCServer  a json rpcserver object
    64  type JSONRPCServer struct {
    65  	jrpc *Turingchain
    66  	s    *rpc.Server
    67  	l    net.Listener
    68  }
    69  
    70  // Close json rpcserver close
    71  func (s *JSONRPCServer) Close() {
    72  	if s.l != nil {
    73  		err := s.l.Close()
    74  		if err != nil {
    75  			log.Error("JSONRPCServer close", "err", err)
    76  		}
    77  	}
    78  	if s.jrpc != nil {
    79  		s.jrpc.cli.Close()
    80  	}
    81  }
    82  
    83  func checkBasicAuth(r *http.Request) bool {
    84  	if rpcCfg.JrpcUserName == "" && rpcCfg.JrpcUserPasswd == "" {
    85  		return true
    86  	}
    87  
    88  	s := strings.SplitN(r.Header.Get("Authorization"), " ", 2)
    89  	if len(s) != 2 {
    90  		return false
    91  	}
    92  
    93  	b, err := base64.StdEncoding.DecodeString(s[1])
    94  	if err != nil {
    95  		return false
    96  	}
    97  
    98  	pair := strings.SplitN(string(b), ":", 2)
    99  	if len(pair) != 2 {
   100  		return false
   101  	}
   102  	return pair[0] == rpcCfg.JrpcUserName && pair[1] == rpcCfg.JrpcUserPasswd
   103  }
   104  
   105  func checkIPWhitelist(addr string) bool {
   106  	//回环网络直接允许
   107  	ip := net.ParseIP(addr)
   108  	if ip.IsLoopback() {
   109  		return true
   110  	}
   111  	ipv4 := ip.To4()
   112  	if ipv4 != nil {
   113  		addr = ipv4.String()
   114  	}
   115  	if _, ok := remoteIPWhitelist["0.0.0.0"]; ok {
   116  		return true
   117  	}
   118  	if _, ok := remoteIPWhitelist[addr]; ok {
   119  		return true
   120  	}
   121  	return false
   122  }
   123  
   124  func checkJrpcFuncWhitelist(funcName string) bool {
   125  
   126  	if _, ok := jrpcFuncWhitelist["*"]; ok {
   127  		return true
   128  	}
   129  
   130  	if _, ok := jrpcFuncWhitelist[funcName]; ok {
   131  		return true
   132  	}
   133  	return false
   134  }
   135  func checkGrpcFuncWhitelist(funcName string) bool {
   136  
   137  	if _, ok := grpcFuncWhitelist["*"]; ok {
   138  		return true
   139  	}
   140  
   141  	if _, ok := grpcFuncWhitelist[funcName]; ok {
   142  		return true
   143  	}
   144  	return false
   145  }
   146  func checkJrpcFuncBlacklist(funcName string) bool {
   147  	if _, ok := jrpcFuncBlacklist[funcName]; ok {
   148  		return true
   149  	}
   150  	return false
   151  }
   152  func checkGrpcFuncBlacklist(funcName string) bool {
   153  	if _, ok := grpcFuncBlacklist[funcName]; ok {
   154  		return true
   155  	}
   156  	return false
   157  }
   158  
   159  // Close grpcserver close
   160  func (j *Grpcserver) Close() {
   161  	if j == nil {
   162  		return
   163  	}
   164  	if j.l != nil {
   165  		err := j.l.Close()
   166  		if err != nil {
   167  			log.Error("Grpcserver close", "err", err)
   168  		}
   169  	}
   170  	if j.grpc != nil {
   171  		j.grpc.cli.Close()
   172  	}
   173  }
   174  
   175  // NewGRpcServer new grpcserver object
   176  func NewGRpcServer(c queue.Client, api client.QueueProtocolAPI) *Grpcserver {
   177  	s := &Grpcserver{grpc: &Grpc{}}
   178  	s.grpc.cli.Init(c, api)
   179  	var opts []grpc.ServerOption
   180  	//register interceptor
   181  	//var interceptor grpc.UnaryServerInterceptor
   182  	interceptor := func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) {
   183  		if err := auth(ctx, info); err != nil {
   184  			return nil, err
   185  		}
   186  		// Continue processing the request
   187  		return handler(ctx, req)
   188  	}
   189  	opts = append(opts, grpc.UnaryInterceptor(interceptor))
   190  	if rpcCfg.EnableTLS {
   191  		creds, err := credentials.NewServerTLSFromFile(rpcCfg.CertFile, rpcCfg.KeyFile)
   192  		if err != nil {
   193  			panic(fmt.Sprintf("err=%s, if cert.pem not found, run turingchain-cli cert --host=127.0.0.1 to create", err.Error()))
   194  		}
   195  		credsOps := grpc.Creds(creds)
   196  		opts = append(opts, credsOps)
   197  	}
   198  
   199  	kp := keepalive.EnforcementPolicy{
   200  		MinTime:             10 * time.Second,
   201  		PermitWithoutStream: true,
   202  	}
   203  	opts = append(opts, grpc.KeepaliveEnforcementPolicy(kp))
   204  
   205  	server := grpc.NewServer(opts...)
   206  	s.s = server
   207  	types.RegisterTuringchainServer(server, s.grpc)
   208  	return s
   209  }
   210  
   211  // NewJSONRPCServer new json rpcserver object
   212  func NewJSONRPCServer(c queue.Client, api client.QueueProtocolAPI) *JSONRPCServer {
   213  	j := &JSONRPCServer{jrpc: &Turingchain{}}
   214  	j.jrpc.cli.Init(c, api)
   215  	if c.GetConfig().IsPara() {
   216  		grpcCli, err := grpcclient.NewMainChainClient(c.GetConfig(), "")
   217  		if err != nil {
   218  			panic(err)
   219  		}
   220  		j.jrpc.mainGrpcCli = grpcCli
   221  	}
   222  	server := rpc.NewServer()
   223  	j.s = server
   224  	err := server.RegisterName("Turingchain", j.jrpc)
   225  	if err != nil {
   226  		return nil
   227  	}
   228  	return j
   229  }
   230  
   231  // RPC a type object
   232  type RPC struct {
   233  	cfg  *types.RPC
   234  	gapi *Grpcserver
   235  	japi *JSONRPCServer
   236  	c    queue.Client
   237  	api  client.QueueProtocolAPI
   238  }
   239  
   240  // InitCfg  interfaces
   241  func InitCfg(cfg *types.RPC) {
   242  	rpcCfg = cfg
   243  	InitIPWhitelist(cfg)
   244  	InitJrpcFuncWhitelist(cfg)
   245  	InitGrpcFuncWhitelist(cfg)
   246  	InitJrpcFuncBlacklist(cfg)
   247  	InitGrpcFuncBlacklist(cfg)
   248  	InitFilterPrintFuncBlacklist()
   249  }
   250  
   251  // New produce a rpc by cfg
   252  func New(cfg *types.TuringchainConfig) *RPC {
   253  	mcfg := cfg.GetModuleConfig().RPC
   254  	InitCfg(mcfg)
   255  	if mcfg.EnableTrace {
   256  		grpc.EnableTracing = true
   257  	}
   258  	return &RPC{cfg: mcfg}
   259  }
   260  
   261  // SetAPI set api of rpc
   262  func (r *RPC) SetAPI(api client.QueueProtocolAPI) {
   263  	r.api = api
   264  }
   265  
   266  // SetQueueClient set queue client
   267  func (r *RPC) SetQueueClient(c queue.Client) {
   268  	gapi := NewGRpcServer(c, r.api)
   269  	japi := NewJSONRPCServer(c, r.api)
   270  	r.gapi = gapi
   271  	r.japi = japi
   272  	r.c = c
   273  	//注册系统rpc
   274  	pluginmgr.AddRPC(r)
   275  	r.Listen()
   276  }
   277  
   278  // SetQueueClientNoListen  set queue client with  no listen
   279  func (r *RPC) SetQueueClientNoListen(c queue.Client) {
   280  	gapi := NewGRpcServer(c, r.api)
   281  	japi := NewJSONRPCServer(c, r.api)
   282  	r.gapi = gapi
   283  	r.japi = japi
   284  	r.c = c
   285  }
   286  
   287  // Listen rpc listen
   288  func (r *RPC) Listen() (port1 int, port2 int) {
   289  	var err error
   290  	for i := 0; i < 10; i++ {
   291  		port1, err = r.gapi.Listen()
   292  		if err != nil {
   293  			log.Error("Grpc Listen", "err", err)
   294  			time.Sleep(time.Second)
   295  			continue
   296  		}
   297  		break
   298  	}
   299  	for i := 0; i < 10; i++ {
   300  		port2, err = r.japi.Listen()
   301  		if err != nil {
   302  			log.Error("Jrpc Listen", "err", err)
   303  			time.Sleep(time.Second)
   304  			continue
   305  		}
   306  		break
   307  	}
   308  	log.Info("rpc Listen ports", "grpc", port1, "jrpc", port2)
   309  	//sleep for a while
   310  	time.Sleep(time.Millisecond)
   311  	return port1, port2
   312  }
   313  
   314  // GetQueueClient get queue client
   315  func (r *RPC) GetQueueClient() queue.Client {
   316  	return r.c
   317  }
   318  
   319  // GRPC return grpc rpc
   320  func (r *RPC) GRPC() *grpc.Server {
   321  	return r.gapi.s
   322  }
   323  
   324  // JRPC return jrpc
   325  func (r *RPC) JRPC() *rpc.Server {
   326  	return r.japi.s
   327  }
   328  
   329  // Close rpc close
   330  func (r *RPC) Close() {
   331  	if r.gapi != nil {
   332  		r.gapi.Close()
   333  	}
   334  	if r.japi != nil {
   335  		r.japi.Close()
   336  	}
   337  }
   338  
   339  // InitIPWhitelist init ip whitelist
   340  func InitIPWhitelist(cfg *types.RPC) {
   341  	if len(cfg.Whitelist) == 0 && len(cfg.Whitlist) == 0 {
   342  		remoteIPWhitelist["127.0.0.1"] = true
   343  		return
   344  	}
   345  	if len(cfg.Whitelist) == 1 && cfg.Whitelist[0] == "*" {
   346  		remoteIPWhitelist["0.0.0.0"] = true
   347  		return
   348  	}
   349  	if len(cfg.Whitlist) == 1 && cfg.Whitlist[0] == "*" {
   350  		remoteIPWhitelist["0.0.0.0"] = true
   351  		return
   352  	}
   353  	if len(cfg.Whitelist) != 0 {
   354  		for _, addr := range cfg.Whitelist {
   355  			remoteIPWhitelist[addr] = true
   356  		}
   357  		return
   358  	}
   359  	if len(cfg.Whitlist) != 0 {
   360  		for _, addr := range cfg.Whitlist {
   361  			remoteIPWhitelist[addr] = true
   362  		}
   363  		return
   364  	}
   365  
   366  }
   367  
   368  // InitJrpcFuncWhitelist init jrpc function whitelist
   369  func InitJrpcFuncWhitelist(cfg *types.RPC) {
   370  	if len(cfg.JrpcFuncWhitelist) == 0 {
   371  		jrpcFuncWhitelist["*"] = true
   372  		return
   373  	}
   374  	if len(cfg.JrpcFuncWhitelist) == 1 && cfg.JrpcFuncWhitelist[0] == "*" {
   375  		jrpcFuncWhitelist["*"] = true
   376  		return
   377  	}
   378  	for _, funcName := range cfg.JrpcFuncWhitelist {
   379  		jrpcFuncWhitelist[funcName] = true
   380  	}
   381  }
   382  
   383  // InitGrpcFuncWhitelist init grpc function whitelist
   384  func InitGrpcFuncWhitelist(cfg *types.RPC) {
   385  	if len(cfg.GrpcFuncWhitelist) == 0 {
   386  		grpcFuncWhitelist["*"] = true
   387  		return
   388  	}
   389  	if len(cfg.GrpcFuncWhitelist) == 1 && cfg.GrpcFuncWhitelist[0] == "*" {
   390  		grpcFuncWhitelist["*"] = true
   391  		return
   392  	}
   393  	for _, funcName := range cfg.GrpcFuncWhitelist {
   394  		grpcFuncWhitelist[funcName] = true
   395  	}
   396  }
   397  
   398  // InitJrpcFuncBlacklist init jrpc function blacklist
   399  func InitJrpcFuncBlacklist(cfg *types.RPC) {
   400  	if len(cfg.JrpcFuncBlacklist) == 0 {
   401  		jrpcFuncBlacklist["CloseQueue"] = true
   402  		return
   403  	}
   404  	for _, funcName := range cfg.JrpcFuncBlacklist {
   405  		jrpcFuncBlacklist[funcName] = true
   406  	}
   407  
   408  }
   409  
   410  // InitGrpcFuncBlacklist init grpc function blacklist
   411  func InitGrpcFuncBlacklist(cfg *types.RPC) {
   412  	if len(cfg.GrpcFuncBlacklist) == 0 {
   413  		grpcFuncBlacklist["CloseQueue"] = true
   414  		return
   415  	}
   416  	for _, funcName := range cfg.GrpcFuncBlacklist {
   417  		grpcFuncBlacklist[funcName] = true
   418  	}
   419  }
   420  
   421  // InitFilterPrintFuncBlacklist rpc模块打印requet信息时需要过滤掉一些敏感接口的入参打印,比如钱包密码相关的
   422  func InitFilterPrintFuncBlacklist() {
   423  	rpcFilterPrintFuncBlacklist["UnLock"] = true
   424  	rpcFilterPrintFuncBlacklist["SetPasswd"] = true
   425  	rpcFilterPrintFuncBlacklist["GetSeed"] = true
   426  	rpcFilterPrintFuncBlacklist["SaveSeed"] = true
   427  	rpcFilterPrintFuncBlacklist["ImportPrivkey"] = true
   428  }
   429  
   430  func checkFilterPrintFuncBlacklist(funcName string) bool {
   431  	if _, ok := rpcFilterPrintFuncBlacklist[funcName]; ok {
   432  		return true
   433  	}
   434  	return false
   435  }