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 }