cubefs

Форк
0
/
auth_proto.go 
796 строк · 26.1 Кб
1
// Copyright 2018 The CubeFS Authors.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12
// implied. See the License for the specific language governing
13
// permissions and limitations under the License.
14

15
package proto
16

17
import (
18
	"encoding/base64"
19
	"encoding/binary"
20
	"encoding/json"
21
	"fmt"
22
	"io"
23
	"net/http"
24
	"net/url"
25
	"regexp"
26
	"time"
27

28
	"github.com/cubefs/cubefs/util/caps"
29
	"github.com/cubefs/cubefs/util/cryptoutil"
30
	"github.com/cubefs/cubefs/util/keystore"
31
)
32

33
// ServiceID defines the type of tickets
34
type ServiceID uint32
35

36
// MsgType defines the type of req/resp for message
37
type MsgType uint32
38

39
// Nonce defines the nonce to mitigate the replay attack
40
type Nonce uint64
41

42
const (
43
	APIRsc          = "API"
44
	APIAccess       = "access"
45
	capSeparator    = ":"
46
	reqLiveLength   = 10
47
	ClientMessage   = "Token"
48
	OwnerVOLRsc     = "OwnerVOL"
49
	NoneOwnerVOLRsc = "NoneOwnerVOL"
50
	VOLAccess       = "*"
51
)
52

53
// api
54
const (
55
	// Client APIs
56
	ClientGetTicket = "/client/getticket"
57

58
	// Admin APIs
59
	AdminCreateKey  = "/admin/createkey"
60
	AdminDeleteKey  = "/admin/deletekey"
61
	AdminGetKey     = "/admin/getkey"
62
	AdminAddCaps    = "/admin/addcaps"
63
	AdminDeleteCaps = "/admin/deletecaps"
64
	AdminGetCaps    = "/admin/getcaps"
65

66
	// raft node APIs
67
	AdminAddRaftNode    = "/admin/addraftnode"
68
	AdminRemoveRaftNode = "/admin/removeraftnode"
69

70
	// Object node APIs
71
	OSAddCaps    = "/os/addcaps"
72
	OSDeleteCaps = "/os/deletecaps"
73
	OSGetCaps    = "/os/getcaps"
74
)
75

76
const (
77
	// AuthServiceID defines ticket for authnode access (not supported)
78
	AuthServiceID = "AuthService"
79

80
	// MasterServiceID defines ticket for master access
81
	MasterServiceID = "MasterService"
82

83
	// MetaServiceID defines ticket for metanode access (not supported)
84
	MetaServiceID = "MetanodeService"
85

86
	// DataServiceID defines ticket for datanode access (not supported)
87
	DataServiceID = "DatanodeService"
88

89
	// ObjectServiceID defines ticket for objectnode access
90
	ObjectServiceID = "ObjectService"
91
)
92

93
const (
94
	MasterNode = "master"
95
	MetaNode   = "metanode"
96
	DataNode   = "datanode"
97
)
98

99
const (
100
	// MsgAuthBase define the starting value for auth message
101
	MsgAuthBase MsgType = 0x100000
102

103
	// MsgAuthTicketReq request type for an auth ticket
104
	MsgAuthTicketReq MsgType = MsgAuthBase + 0x10000
105

106
	// MsgAuthTicketResp respose type for an auth ticket
107
	MsgAuthTicketResp MsgType = MsgAuthBase + 0x10001
108

109
	// MsgMasterTicketReq request type for a master ticket
110
	MsgMasterTicketReq MsgType = MsgAuthBase + 0x20000
111

112
	// MsgMasterTicketResp response type for a master ticket
113
	MsgMasterTicketResp MsgType = MsgAuthBase + 0x20001
114

115
	// MsgMetaTicketReq request type for a metanode ticket
116
	MsgMetaTicketReq MsgType = MsgAuthBase + 0x30000
117

118
	// MsgMetaTicketResp response type for a metanode ticket
119
	MsgMetaTicketResp MsgType = MsgAuthBase + 0x30001
120

121
	// MsgDataTicketReq request type for a datanode ticket
122
	MsgDataTicketReq MsgType = MsgAuthBase + 0x40000
123

124
	// MsgDataTicketResp response type for a datanode ticket
125
	MsgDataTicketResp MsgType = MsgAuthBase + 0x40001
126

127
	// MsgAuthCreateKeyReq request type for authnode add key
128
	MsgAuthCreateKeyReq MsgType = MsgAuthBase + 0x51000
129

130
	// MsgAuthCreateKeyResp response type for authnode add key
131
	MsgAuthCreateKeyResp MsgType = MsgAuthBase + 0x51001
132

133
	// MsgAuthDeleteKeyReq request type for authnode delete key
134
	MsgAuthDeleteKeyReq MsgType = MsgAuthBase + 0x52000
135

136
	// MsgAuthDeleteKeyResp response type for authnode delete key
137
	MsgAuthDeleteKeyResp MsgType = MsgAuthBase + 0x52001
138

139
	// MsgAuthGetKeyReq request type for authnode get key info
140
	MsgAuthGetKeyReq MsgType = MsgAuthBase + 0x53000
141

142
	// MsgAuthGetKeyResp response type for authnode get key info
143
	MsgAuthGetKeyResp MsgType = MsgAuthBase + 0x53001
144

145
	// MsgAuthAddCapsReq request type for authnode add caps
146
	MsgAuthAddCapsReq MsgType = MsgAuthBase + 0x54000
147

148
	// MsgAuthAddCapsResp response type for authnode add caps
149
	MsgAuthAddCapsResp MsgType = MsgAuthBase + 0x54001
150

151
	// MsgAuthDeleteCapsReq request type for authnode add caps
152
	MsgAuthDeleteCapsReq MsgType = MsgAuthBase + 0x55000
153

154
	// MsgAuthDeleteCapsResp response type for authnode add caps
155
	MsgAuthDeleteCapsResp MsgType = MsgAuthBase + 0x55001
156

157
	// MsgAuthGetCapsReq request type for authnode add caps
158
	MsgAuthGetCapsReq MsgType = MsgAuthBase + 0x56000
159

160
	// MsgAuthGetCapsResp response type for authnode add caps
161
	MsgAuthGetCapsResp MsgType = MsgAuthBase + 0x56001
162

163
	// MsgAuthAddRaftNodeReq request type for authnode add node
164
	MsgAuthAddRaftNodeReq MsgType = MsgAuthBase + 0x57000
165

166
	// MsgAuthAddRaftNodeResp response type for authnode remove node
167
	MsgAuthAddRaftNodeResp MsgType = MsgAuthBase + 0x57001
168

169
	// MsgAuthRemoveRaftNodeReq request type for authnode remove node
170
	MsgAuthRemoveRaftNodeReq MsgType = MsgAuthBase + 0x58000
171

172
	// MsgAuthRemoveRaftNodeResp response type for authnode remove node
173
	MsgAuthRemoveRaftNodeResp MsgType = MsgAuthBase + 0x58001
174

175
	// MsgAuthOSAddCapsReq request type from ObjectNode to add caps
176
	MsgAuthOSAddCapsReq MsgType = MsgAuthBase + 0x61000
177

178
	// MsgAuthOSAddCapsResp request type from ObjectNode to add caps
179
	MsgAuthOSAddCapsResp MsgType = MsgAuthBase + 0x61001
180

181
	// MsgAuthOSDeleteCapsReq request type from ObjectNode to delete caps
182
	MsgAuthOSDeleteCapsReq MsgType = MsgAuthBase + 0x62000
183

184
	// MsgAuthOSDeleteCapsResp request type from ObjectNode to delete caps
185
	MsgAuthOSDeleteCapsResp MsgType = MsgAuthBase + 0x62001
186

187
	// MsgAuthOSGetCapsReq request type from ObjectNode to get caps
188
	MsgAuthOSGetCapsReq MsgType = MsgAuthBase + 0x63000
189

190
	// MsgAuthOSGetCapsResp response type from ObjectNode to get caps
191
	MsgAuthOSGetCapsResp MsgType = MsgAuthBase + 0x63001
192

193
	// MsgMasterAPIAccessReq request type for master api access
194
	MsgMasterAPIAccessReq MsgType = 0x60000
195

196
	// MsgMasterAPIAccessResp response type for master api access
197
	MsgMasterAPIAccessResp MsgType = 0x60001
198

199
	// Master API ClientVol
200
	MsgMasterFetchVolViewReq MsgType = MsgMasterAPIAccessReq + 0x10000
201

202
	// Master API cluster management
203
	MsgMasterClusterFreezeReq    MsgType = MsgMasterAPIAccessReq + 0x20100
204
	MsgMasterAddRaftNodeReq      MsgType = MsgMasterAPIAccessReq + 0x20200
205
	MsgMasterRemoveRaftNodeReq   MsgType = MsgMasterAPIAccessReq + 0x20300
206
	MsgMasterSetNodeInfoReq      MsgType = MsgMasterAPIAccessReq + 0x20400
207
	MsgMasterSetNodeRdOnlyReq    MsgType = MsgMasterAPIAccessReq + 0x20500
208
	MsgMasterAutoDecommissionReq MsgType = MsgMasterAPIAccessReq + 0x20600
209

210
	// Master API volume management
211
	MsgMasterCreateVolReq MsgType = MsgMasterAPIAccessReq + 0x30100
212
	MsgMasterDeleteVolReq MsgType = MsgMasterAPIAccessReq + 0x30200
213
	MsgMasterUpdateVolReq MsgType = MsgMasterAPIAccessReq + 0x30300
214
	MsgMasterVolShrinkReq MsgType = MsgMasterAPIAccessReq + 0x30400
215
	MsgMasterVolExpandReq MsgType = MsgMasterAPIAccessReq + 0x30500
216

217
	// Master API meta partition management
218
	MsgMasterLoadMetaPartitionReq         MsgType = MsgMasterAPIAccessReq + 0x40100
219
	MsgMasterDecommissionMetaPartitionReq MsgType = MsgMasterAPIAccessReq + 0x40200
220
	MsgMasterChangeMetaPartitionLeaderReq MsgType = MsgMasterAPIAccessReq + 0x40300
221
	MsgMasterCreateMetaPartitionReq       MsgType = MsgMasterAPIAccessReq + 0x40400
222
	MsgMasterAddMetaReplicaReq            MsgType = MsgMasterAPIAccessReq + 0x40500
223
	MsgMasterDeleteMetaReplicaReq         MsgType = MsgMasterAPIAccessReq + 0x40600
224
	MsgMasterQosUpdateReq                 MsgType = MsgMasterAPIAccessReq + 0x40700
225
	MsgMasterQosUpdateZoneLimitReq        MsgType = MsgMasterAPIAccessReq + 0x40800
226
	MsgMasterQosUpdateMasterLimitReq      MsgType = MsgMasterAPIAccessReq + 0x40900
227
	MsgMasterQosUpdateClientParamReq      MsgType = MsgMasterAPIAccessReq + 0x40a00
228

229
	// Master API data partition management
230
	MsgMasterCreateDataPartitionReq       MsgType = MsgMasterAPIAccessReq + 0x50100
231
	MsgMasterDataPartitionChangeLeaderReq MsgType = MsgMasterAPIAccessReq + 0x50200
232
	MsgMasterLoadDataPartitionReq         MsgType = MsgMasterAPIAccessReq + 0x50300
233
	MsgMasterDecommissionDataPartitionReq MsgType = MsgMasterAPIAccessReq + 0x50400
234
	MsgMasterAddDataReplicaReq            MsgType = MsgMasterAPIAccessReq + 0x50500
235
	MsgMasterDeleteDataReplicaReq         MsgType = MsgMasterAPIAccessReq + 0x50600
236
	MsgMasterSetDpRdOnlyReq               MsgType = MsgMasterAPIAccessReq + 0x50700
237
	MsgMasterReportLackDataPartitions     MsgType = MsgMasterAPIAccessReq + 0x50800
238

239
	// Master API meta node management
240
	MsgMasterAddMetaNodeReq          MsgType = MsgMasterAPIAccessReq + 0x60100
241
	MsgMasterDecommissionMetaNodeReq MsgType = MsgMasterAPIAccessReq + 0x60200
242
	MsgMasterMigrateMetaNodeReq      MsgType = MsgMasterAPIAccessReq + 0x60300
243
	MsgMasterSetMetaNodeThresholdReq MsgType = MsgMasterAPIAccessReq + 0x60400
244
	MsgMasterUpdateMetaNodeReq       MsgType = MsgMasterAPIAccessReq + 0x60500
245

246
	// Master API data node management
247
	MsgMasterAddDataNodeReq                MsgType = MsgMasterAPIAccessReq + 0x70100
248
	MsgMasterDecommissionDataNodeReq       MsgType = MsgMasterAPIAccessReq + 0x70200
249
	MsgMasterMigrateDataNodeReq            MsgType = MsgMasterAPIAccessReq + 0x70300
250
	MsgMasterCancelDecommissionDataNodeReq MsgType = MsgMasterAPIAccessReq + 0x70400
251
	MsgMasterDecommissionDiskReq           MsgType = MsgMasterAPIAccessReq + 0x70500
252
	MsgMasterUpdateNodeSetCapcityReq       MsgType = MsgMasterAPIAccessReq + 0x70600
253
	MsgMasterUpdateNodeSetIdReq            MsgType = MsgMasterAPIAccessReq + 0x70700
254
	MsgMasterUpdateDomainDataUseRatioReq   MsgType = MsgMasterAPIAccessReq + 0x70800
255
	MsgMasterUpdateZoneExcludeRatioReq     MsgType = MsgMasterAPIAccessReq + 0x70900
256
	MsgMasterRecommissionDiskReq           MsgType = MsgMasterAPIAccessReq + 0x70a00
257

258
	// Master API user management
259
	MsgMasterUserCreateReq          MsgType = MsgMasterAPIAccessReq + 0x80100
260
	MsgMasterUserDeleteReq          MsgType = MsgMasterAPIAccessReq + 0x80200
261
	MsgMasterUserUpdateReq          MsgType = MsgMasterAPIAccessReq + 0x80300
262
	MsgMasterUserUpdatePolicyReq    MsgType = MsgMasterAPIAccessReq + 0x80400
263
	MsgMasterUserRemovePolicyReq    MsgType = MsgMasterAPIAccessReq + 0x80500
264
	MsgMasterUserDeleteVolPolicyReq MsgType = MsgMasterAPIAccessReq + 0x80600
265
	MsgMasterUserTransferVolReq     MsgType = MsgMasterAPIAccessReq + 0x80700
266

267
	// Master API zone management
268
	MsgMasterUpdateZoneReq MsgType = MsgMasterAPIAccessReq + 0x90100
269
)
270

271
// HTTPAuthReply uniform response structure
272
type HTTPAuthReply = HTTPReply
273

274
// MsgType2ResourceMap define the mapping from message type to resource
275
var MsgType2ResourceMap = map[MsgType]string{
276
	MsgAuthCreateKeyReq:      "auth:createkey",
277
	MsgAuthDeleteKeyReq:      "auth:deletekey",
278
	MsgAuthGetKeyReq:         "auth:getkey",
279
	MsgAuthAddCapsReq:        "auth:addcaps",
280
	MsgAuthDeleteCapsReq:     "auth:deletecaps",
281
	MsgAuthGetCapsReq:        "auth:getcaps",
282
	MsgAuthAddRaftNodeReq:    "auth:addnode",
283
	MsgAuthRemoveRaftNodeReq: "auth:removenode",
284
	MsgAuthOSAddCapsReq:      "auth:osaddcaps",
285
	MsgAuthOSDeleteCapsReq:   "auth:osdeletecaps",
286
	MsgAuthOSGetCapsReq:      "auth:osgetcaps",
287

288
	MsgMasterFetchVolViewReq: "master:getvol",
289

290
	// Master API cluster management
291
	MsgMasterClusterFreezeReq:    "master:clusterfreeze",
292
	MsgMasterAddRaftNodeReq:      "master:addraftnode",
293
	MsgMasterRemoveRaftNodeReq:   "master:removeraftnode",
294
	MsgMasterSetNodeInfoReq:      "master:setnodeinfo",
295
	MsgMasterSetNodeRdOnlyReq:    "master:sernoderdonly",
296
	MsgMasterAutoDecommissionReq: "master:autodecommission",
297

298
	// Master API volume management
299
	MsgMasterCreateVolReq: "master:createvol",
300
	MsgMasterDeleteVolReq: "master:deletevol",
301
	MsgMasterUpdateVolReq: "master:updatevol",
302
	MsgMasterVolShrinkReq: "master:volshrink",
303
	MsgMasterVolExpandReq: "master:volexpand",
304

305
	// Master API meta partition management
306
	MsgMasterLoadMetaPartitionReq:         "master:loadmetapartition",
307
	MsgMasterDecommissionMetaPartitionReq: "master:decommissionmetapartition",
308
	MsgMasterChangeMetaPartitionLeaderReq: "master:changemetapartitionleader",
309
	MsgMasterCreateMetaPartitionReq:       "master:createmetapartition",
310
	MsgMasterAddMetaReplicaReq:            "master:addmetareplica",
311
	MsgMasterDeleteMetaReplicaReq:         "master:deletemetareplica",
312
	MsgMasterQosUpdateReq:                 "master:qosupdate",
313
	MsgMasterQosUpdateZoneLimitReq:        "master:qosupdatezonelimit",
314
	MsgMasterQosUpdateMasterLimitReq:      "master:qosupdatemasterlimit",
315
	MsgMasterQosUpdateClientParamReq:      "master:qosupdateclientparam",
316

317
	// Master API data partition management
318
	MsgMasterCreateDataPartitionReq:       "master:createdatapartition",
319
	MsgMasterDataPartitionChangeLeaderReq: "master:changedatapartitionleader",
320
	MsgMasterLoadDataPartitionReq:         "master:loaddatapartition",
321
	MsgMasterDecommissionDataPartitionReq: "master:decommissiondatapartition",
322
	MsgMasterAddDataReplicaReq:            "master:adddatareplica",
323
	MsgMasterDeleteDataReplicaReq:         "master:removedatareplica",
324
	MsgMasterSetDpRdOnlyReq:               "master:setdprdonly",
325
	MsgMasterReportLackDataPartitions:     "master:reportLackDataPartitions",
326

327
	// Master API meta node management
328
	MsgMasterAddMetaNodeReq:          "master:addmetanode",
329
	MsgMasterDecommissionMetaNodeReq: "master:decommissionmetanode",
330
	MsgMasterMigrateMetaNodeReq:      "master:migratemetanode",
331
	MsgMasterSetMetaNodeThresholdReq: "master:setmetanodethreshold",
332
	MsgMasterUpdateMetaNodeReq:       "master:updatemetanode",
333

334
	// Master API data node management
335
	MsgMasterAddDataNodeReq:                "master:adddatannode",
336
	MsgMasterDecommissionDataNodeReq:       "master:decommissiondatannode",
337
	MsgMasterMigrateDataNodeReq:            "master:migratedatannode",
338
	MsgMasterCancelDecommissionDataNodeReq: "master:canceldecommissiondatannode",
339
	MsgMasterDecommissionDiskReq:           "master:decommissiondisk",
340
	MsgMasterUpdateNodeSetCapcityReq:       "master:updatenodesetcapcity",
341
	MsgMasterUpdateNodeSetIdReq:            "master:updatenodesetid",
342
	MsgMasterUpdateDomainDataUseRatioReq:   "master:updatedomaindatauseratio",
343
	MsgMasterUpdateZoneExcludeRatioReq:     "master:updatezoneexcluderatio",
344
	MsgMasterRecommissionDiskReq:           "master:recommissiondisk",
345

346
	// Master API user management
347
	MsgMasterUserCreateReq:          "master:usercreate",
348
	MsgMasterUserDeleteReq:          "master:userdelete",
349
	MsgMasterUserUpdateReq:          "master:userupdate",
350
	MsgMasterUserUpdatePolicyReq:    "master:userupdatepolicy",
351
	MsgMasterUserRemovePolicyReq:    "master:userremotepolicy",
352
	MsgMasterUserDeleteVolPolicyReq: "master:userdeletevolpolicy",
353
	MsgMasterUserTransferVolReq:     "master:usertransfervol",
354

355
	// Master API zone management
356
	MsgMasterUpdateZoneReq: "master:updatezone",
357
}
358

359
// AuthGetTicketReq defines the message from client to authnode
360
// use Timestamp as verifier for MITM mitigation
361
// verifier is also used to verify the server identity
362
type AuthGetTicketReq struct {
363
	Type      MsgType `json:"type"`
364
	ClientID  string  `json:"client_id"`
365
	ServiceID string  `json:"service_id"`
366
	Verifier  string  `json:"verifier"`
367
}
368

369
// AuthGetTicketResp defines the message from authnode to client
370
type AuthGetTicketResp struct {
371
	Type       MsgType              `json:"type"`
372
	ClientID   string               `json:"client_id"`
373
	ServiceID  string               `json:"service_id"`
374
	Verifier   int64                `json:"verifier"`
375
	Ticket     string               `json:"ticket"`
376
	SessionKey cryptoutil.CryptoKey `json:"session_key"`
377
}
378

379
// APIAccessReq defines the request for access restful api
380
// use Timestamp as verifier for MITM mitigation
381
// verifier is also used to verify the server identity
382
type APIAccessReq struct {
383
	Type      MsgType `json:"type"`
384
	ClientID  string  `json:"client_id"`
385
	ServiceID string  `json:"service_id"`
386
	Verifier  string  `json:"verifier"`
387
	Ticket    string  `json:"ticket"`
388
}
389

390
// APIAccessResp defines the response for access restful api
391
// use Timestamp as verifier for MITM mitigation
392
// verifier is also used to verify the server identity
393
type APIAccessResp struct {
394
	Type      MsgType `json:"type"`
395
	ClientID  string  `json:"client_id"`
396
	ServiceID string  `json:"service_id"`
397
	Verifier  int64   `json:"verifier"`
398
}
399

400
// AuthAPIAccessReq defines Auth API request
401
type AuthAPIAccessReq struct {
402
	APIReq  APIAccessReq     `json:"api_req"`
403
	KeyInfo keystore.KeyInfo `json:"key_info"`
404
}
405

406
// AuthAPIAccessResp defines the response for creating an key in authnode
407
type AuthAPIAccessResp struct {
408
	APIResp   APIAccessResp    `json:"api_resp"`
409
	KeyInfo   keystore.KeyInfo `json:"key_info"`
410
	AuthIDKey string           `json:"auth_id_key"`
411
}
412

413
// AuthRaftNodeInfo defines raft node information
414
type AuthRaftNodeInfo struct {
415
	ID   uint64 `json:"id"`
416
	Addr string `json:"addr"`
417
}
418

419
// AuthRaftNodeReq defines Auth API request for add/remove a raft node
420
type AuthRaftNodeReq struct {
421
	APIReq       APIAccessReq     `json:"api_req"`
422
	RaftNodeInfo AuthRaftNodeInfo `json:"node_info"`
423
}
424

425
// AuthRaftNodeResp defines Auth API response for add/remove a raft node
426
type AuthRaftNodeResp struct {
427
	APIResp APIAccessResp `json:"api_resp"`
428
	Msg     string        `json:"msg"`
429
}
430

431
// AuthAPIAccessKeystoreReq defines Auth API for put/delete Access Keystore vols
432
type AuthOSAccessKeyReq struct {
433
	APIReq APIAccessReq           `json:"api_req"`
434
	AKCaps keystore.AccessKeyCaps `json:"access_key_caps"`
435
}
436

437
// AuthAPIAccessKeystoreResp defines the response for put/delete Access Keystore vols
438
type AuthOSAccessKeyResp struct {
439
	APIResp APIAccessResp          `json:"api_resp"`
440
	AKCaps  keystore.AccessKeyCaps `json:"access_key_caps"`
441
}
442

443
// IsValidServiceID determine the validity of a serviceID
444
func IsValidServiceID(serviceID string) (err error) {
445
	if serviceID != AuthServiceID && serviceID != MasterServiceID && serviceID != MetaServiceID && serviceID != DataServiceID {
446
		err = fmt.Errorf("invalid service ID [%s]", serviceID)
447
		return
448
	}
449
	return
450
}
451

452
// IsValidMsgReqType determine the validity of a message type
453
func IsValidMsgReqType(serviceID string, msgType MsgType) (err error) {
454
	b := false
455
	switch serviceID {
456
	case "AuthService":
457
		fallthrough
458
	case "MasterService":
459
		if msgType|MsgAuthBase != 0 {
460
			b = true
461
		}
462
	default:
463
		// do nothing
464
	}
465
	if !b {
466
		err = fmt.Errorf("invalid request type [%x] and serviceID[%s]", msgType, serviceID)
467
		return
468
	}
469
	return
470
}
471

472
// IsValidClientID determine the validity of a clientID
473
func IsValidClientID(id string) (err error) {
474
	re := regexp.MustCompile("^[A-Za-z]{1,1}[A-Za-z0-9_]{0,20}$")
475
	if !re.MatchString(id) {
476
		err = fmt.Errorf("clientID invalid format [%s]", id)
477
		return
478
	}
479
	return
480
}
481

482
// ParseAuthReply parse the response from auth
483
func ParseAuthReply(body []byte) (jobj HTTPAuthReply, err error) {
484
	if err = json.Unmarshal(body, &jobj); err != nil {
485
		return
486
	}
487
	if jobj.Code != 0 {
488
		err = fmt.Errorf(jobj.Msg)
489
		return
490
	}
491
	return
492
}
493

494
// GetDataFromResp extract data from response
495
func GetDataFromResp(body []byte, key []byte) (plaintext []byte, err error) {
496
	jobj, err := ParseAuthReply(body)
497
	if err != nil {
498
		return
499
	}
500
	data := fmt.Sprint(jobj.Data)
501

502
	if plaintext, err = cryptoutil.DecodeMessage(data, key); err != nil {
503
		return
504
	}
505

506
	return
507
}
508

509
// ParseAuthGetTicketResp parse and validate the auth get ticket resp
510
func ParseAuthGetTicketResp(body []byte, key []byte) (resp AuthGetTicketResp, err error) {
511
	var plaintext []byte
512

513
	if plaintext, err = GetDataFromResp(body, key); err != nil {
514
		return
515
	}
516

517
	if err = json.Unmarshal(plaintext, &resp); err != nil {
518
		return
519
	}
520

521
	return
522
}
523

524
// ParseAuthAPIAccessResp parse and validate the auth api access resp
525
func ParseAuthAPIAccessResp(body []byte, key []byte) (resp AuthAPIAccessResp, err error) {
526
	var plaintext []byte
527

528
	if plaintext, err = GetDataFromResp(body, key); err != nil {
529
		return
530
	}
531

532
	if err = json.Unmarshal(plaintext, &resp); err != nil {
533
		return
534
	}
535

536
	return
537
}
538

539
// ParseAuthRaftNodeResp parse and validate the auth raft node resp
540
func ParseAuthRaftNodeResp(body []byte, key []byte) (resp AuthRaftNodeResp, err error) {
541
	var plaintext []byte
542

543
	if plaintext, err = GetDataFromResp(body, key); err != nil {
544
		return
545
	}
546

547
	if err = json.Unmarshal(plaintext, &resp); err != nil {
548
		return
549
	}
550

551
	return
552
}
553

554
func ParseAuthOSAKResp(body []byte, key []byte) (resp AuthOSAccessKeyResp, err error) {
555
	var plaintext []byte
556

557
	if plaintext, err = GetDataFromResp(body, key); err != nil {
558
		return
559
	}
560

561
	if err = json.Unmarshal(plaintext, &resp); err != nil {
562
		return
563
	}
564

565
	return
566
}
567

568
func ExtractTicket(str string, key []byte) (ticket cryptoutil.Ticket, err error) {
569
	var plaintext []byte
570

571
	if plaintext, err = cryptoutil.DecodeMessage(str, key); err != nil {
572
		return
573
	}
574

575
	if err = json.Unmarshal(plaintext, &ticket); err != nil {
576
		return
577
	}
578

579
	return
580
}
581

582
func checkTicketCaps(ticket *cryptoutil.Ticket, kind string, cap string) (err error) {
583
	c := new(caps.Caps)
584
	if err = c.Init(ticket.Caps); err != nil {
585
		return
586
	}
587
	if b := c.ContainCaps(kind, cap); !b {
588
		err = fmt.Errorf("no permission to access %v", kind)
589
		return
590
	}
591
	return
592
}
593

594
// ParseVerifier checks the verifier structure for replay attack mitigation
595
func ParseVerifier(verifier string, key []byte) (ts int64, err error) {
596
	var plainttext []byte
597

598
	if plainttext, err = cryptoutil.DecodeMessage(verifier, key); err != nil {
599
		return
600
	}
601

602
	ts = int64(binary.LittleEndian.Uint64(plainttext))
603

604
	if time.Now().Unix()-ts >= reqLiveLength { // mitigate replay attack
605
		err = fmt.Errorf("req verifier is timeout [%d] >= [%d]", time.Now().Unix()-ts, reqLiveLength)
606
		return
607
	}
608

609
	return
610
}
611

612
// VerifyAPIAccessReqIDs verify the req IDs
613
func VerifyAPIAccessReqIDs(req *APIAccessReq) (err error) {
614
	if err = IsValidClientID(req.ClientID); err != nil {
615
		err = fmt.Errorf("IsValidClientID failed: %s", err.Error())
616
		return
617
	}
618

619
	if err = IsValidServiceID(req.ServiceID); err != nil {
620
		err = fmt.Errorf("IsValidServiceID failed: %s", err.Error())
621
		return
622
	}
623

624
	if err = IsValidMsgReqType(req.ServiceID, req.Type); err != nil {
625
		err = fmt.Errorf("IsValidMsgReqType failed: %s", err.Error())
626
		return
627
	}
628
	return
629
}
630

631
// ExtractAPIAccessTicket verify ticket validity
632
func ExtractAPIAccessTicket(req *APIAccessReq, key []byte) (ticket cryptoutil.Ticket, ts int64, err error) {
633
	if ticket, err = ExtractTicket(req.Ticket, key); err != nil {
634
		err = fmt.Errorf("extractTicket failed: %s", err.Error())
635
		return
636
	}
637

638
	if time.Now().Unix() >= ticket.Exp {
639
		err = ErrExpiredTicket
640
		return
641
	}
642

643
	if ts, err = ParseVerifier(req.Verifier, ticket.SessionKey.Key); err != nil {
644
		err = fmt.Errorf("parseVerifier failed: %s", err.Error())
645
		return
646
	}
647

648
	return
649
}
650

651
// CheckAPIAccessCaps checks capability
652
func CheckAPIAccessCaps(ticket *cryptoutil.Ticket, rscType string, mp MsgType, action string) (err error) {
653
	if _, ok := MsgType2ResourceMap[mp]; !ok {
654
		err = fmt.Errorf("MsgType2ResourceMap key not found [%d]", mp)
655
		return
656
	}
657

658
	rule := MsgType2ResourceMap[mp] + capSeparator + action
659

660
	if err = checkTicketCaps(ticket, rscType, rule); err != nil {
661
		err = fmt.Errorf("checkTicketCaps failed: %s", err.Error())
662
		return
663
	}
664
	return
665
}
666

667
func GenAuthIDKey(id string, authKey []byte) (authIDKey string, err error) {
668
	type AuthIDKey struct {
669
		ID      string `json:"id"`
670
		AuthKey []byte `json:"auth_key"`
671
	}
672
	tmpAuthIDKey := AuthIDKey{
673
		ID:      id,
674
		AuthKey: authKey,
675
	}
676
	var jAuthIDKey []byte
677
	if jAuthIDKey, err = json.Marshal(tmpAuthIDKey); err != nil {
678
		err = fmt.Errorf("json marshal authIDKey failed %s", err.Error())
679
		return
680
	}
681
	authIDKey = cryptoutil.Base64Encode(jAuthIDKey)
682
	return
683
}
684

685
func ExtractIDAndAuthKey(authIDKey string) (id string, authKey []byte, err error) {
686
	type AuthIDKey struct {
687
		ID      string `json:"id"`
688
		AuthKey string `json:"auth_key"`
689
	}
690
	var jAuthIDKey []byte
691
	jAuthIDKey, err = cryptoutil.Base64Decode(authIDKey)
692
	if err != nil {
693
		err = fmt.Errorf("decode authIDKey failed %s", err.Error())
694
		return
695
	}
696
	tmpAuthIDKey := &AuthIDKey{}
697
	if err = json.Unmarshal(jAuthIDKey, &tmpAuthIDKey); err != nil {
698
		err = fmt.Errorf("json unmarshal authIDKey failed %s", err.Error())
699
		return
700
	}
701
	id = tmpAuthIDKey.ID
702
	authKey = []byte(tmpAuthIDKey.AuthKey)
703
	return
704
}
705

706
func CheckVOLAccessCaps(ticket *cryptoutil.Ticket, volName string, action string, accessNode string) (err error) {
707
	rule := accessNode + capSeparator + volName + capSeparator + action
708

709
	if err = checkTicketCaps(ticket, OwnerVOLRsc, rule); err != nil {
710
		if err = checkTicketCaps(ticket, NoneOwnerVOLRsc, rule); err != nil {
711
			err = fmt.Errorf("checkTicketCaps failed: %s", err.Error())
712
			return
713
		}
714
	}
715

716
	return
717
}
718

719
// VerifyAPIRespComm client verifies commond attributes returned from server
720
func VerifyAPIRespComm(apiResp *APIAccessResp, msg MsgType, clientID string, serviceID string, ts int64) (err error) {
721
	if ts+1 != apiResp.Verifier {
722
		err = fmt.Errorf("verifier verification failed")
723
		return
724
	}
725

726
	if apiResp.Type != msg+1 {
727
		err = fmt.Errorf("msg verification failed")
728
		return
729
	}
730

731
	if apiResp.ClientID != clientID {
732
		err = fmt.Errorf("id verification failed")
733
		return
734
	}
735

736
	if apiResp.ServiceID != serviceID {
737
		err = fmt.Errorf("service id verification failed")
738
		return
739
	}
740
	return
741
}
742

743
// VerifyTicketRespComm verifies the ticket respose from server
744
func VerifyTicketRespComm(ticketResp *AuthGetTicketResp, msg MsgType, clientID string, serviceID string, ts int64) (err error) {
745
	if ts+1 != ticketResp.Verifier {
746
		err = fmt.Errorf("verifier verification failed")
747
		return
748
	}
749

750
	if ticketResp.Type != msg+1 {
751
		err = fmt.Errorf("msg verification failed")
752
		return
753
	}
754

755
	if ticketResp.ClientID != clientID {
756
		err = fmt.Errorf("id verification failed")
757
		return
758
	}
759

760
	if ticketResp.ServiceID != serviceID {
761
		err = fmt.Errorf("service id verification failed")
762
		return
763
	}
764
	return
765
}
766

767
// SendBytes send raw bytes target in http/https protocol
768
func SendBytes(client *http.Client, target string, data []byte) (res []byte, err error) {
769
	message := base64.StdEncoding.EncodeToString(data)
770
	resp, err := client.PostForm(target, url.Values{ClientMessage: {message}})
771
	if err != nil {
772
		err = fmt.Errorf("action[SendData] failed:" + err.Error())
773
		return
774
	}
775
	defer resp.Body.Close()
776
	body, err := io.ReadAll(resp.Body)
777
	if err != nil {
778
		err = fmt.Errorf("action[doRealSend] failed:" + err.Error())
779
		return
780
	}
781
	res = body
782
	return
783
}
784

785
// SendData sends data to target
786
func SendData(client *http.Client, target string, data interface{}) (res []byte, err error) {
787
	messageJSON, err := json.Marshal(data)
788
	if err != nil {
789
		err = fmt.Errorf("action[doRealSend] failed:" + err.Error())
790
		return
791
	}
792
	if res, err = SendBytes(client, target, messageJSON); err != nil {
793
		return
794
	}
795
	return
796
}
797

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.