Skip to content

Commit e63c915

Browse files
committed
[FAB-2969] Access control at CSCC
This change-set does the following: 1. Add access control to cscc by verifying that the caller has appropriate rights. Tests have been modified to cover this access control This change-set comes in the context of: 1. https://jira.hyperledger.org/browse/FAB-2969 Change-Id: If8698026a81b5402b5336c83ec553a8c39f2d8e0 Signed-off-by: Angelo De Caro <adc@zurich.ibm.com>
1 parent fed2efa commit e63c915

File tree

8 files changed

+306
-162
lines changed

8 files changed

+306
-162
lines changed

core/chaincode/exectransaction_test.go

+132-131
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,20 @@ limitations under the License.
1717
package chaincode
1818

1919
import (
20-
"encoding/json"
2120
"fmt"
2221
"math/rand"
2322
"net"
2423
"os"
2524
"path/filepath"
2625
"runtime"
2726
"strconv"
28-
"strings"
2927
"sync"
3028
"testing"
3129
"time"
3230

31+
"encoding/json"
32+
"strings"
33+
3334
"github.com/golang/protobuf/proto"
3435
"github.com/hyperledger/fabric/common/util"
3536
"github.com/hyperledger/fabric/core/common/ccprovider"
@@ -497,27 +498,6 @@ func _(chainID string, _ string) error {
497498
return nil
498499
}
499500

500-
// Test deploy of a transaction
501-
func TestExecuteDeployTransaction(t *testing.T) {
502-
//chaincoe is deployed as part of many tests. No need for a separate one for this
503-
t.Skip()
504-
chainID := util.GetTestChainID()
505-
506-
executeDeployTransaction(t, chainID, "example01", "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example01")
507-
}
508-
509-
// Test deploy of a transaction with a GOPATH with multiple elements
510-
func TestGopathExecuteDeployTransaction(t *testing.T) {
511-
//this is no longer critical as chaincode is assembled in the client side (SDK)
512-
t.Skip()
513-
chainID := util.GetTestChainID()
514-
515-
// add a trailing slash to GOPATH
516-
// and a couple of elements - it doesn't matter what they are
517-
os.Setenv("GOPATH", os.Getenv("GOPATH")+string(os.PathSeparator)+string(os.PathListSeparator)+"/tmp/foo"+string(os.PathListSeparator)+"/tmp/bar")
518-
executeDeployTransaction(t, chainID, "example01", "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example01")
519-
}
520-
521501
// Disable this temporarily.
522502
// TODO: Need to enable this after update chaincode interface of chaincode repo.
523503
// Test deploy of a transaction with a chaincode over HTTP.
@@ -634,6 +614,118 @@ const (
634614
chaincodeExample06JavaPath = "../../examples/chaincode/java/chaincode_example06"
635615
)
636616

617+
func runChaincodeInvokeChaincode(t *testing.T, chainID string, _ string) (err error) {
618+
var ctxt = context.Background()
619+
620+
// Deploy first chaincode
621+
url1 := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02"
622+
623+
cID1 := &pb.ChaincodeID{Name: "example02", Path: url1, Version: "0"}
624+
f := "init"
625+
args := util.ToChaincodeArgs(f, "a", "100", "b", "200")
626+
627+
spec1 := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID1, Input: &pb.ChaincodeInput{Args: args}}
628+
629+
cccid1 := ccprovider.NewCCContext(chainID, "example02", "0", "", false, nil, nil)
630+
631+
var nextBlockNumber uint64
632+
633+
_, err = deploy(ctxt, cccid1, spec1, nextBlockNumber)
634+
nextBlockNumber++
635+
ccID1 := spec1.ChaincodeId.Name
636+
if err != nil {
637+
t.Fail()
638+
t.Logf("Error initializing chaincode %s(%s)", ccID1, err)
639+
theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1})
640+
return
641+
}
642+
643+
t.Logf("deployed chaincode_example02 got cID1:% s,\n ccID1:% s", cID1, ccID1)
644+
645+
time.Sleep(time.Second)
646+
647+
// Deploy second chaincode
648+
url2 := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example04"
649+
650+
cID2 := &pb.ChaincodeID{Name: "example04", Path: url2, Version: "0"}
651+
f = "init"
652+
args = util.ToChaincodeArgs(f, "e", "0")
653+
654+
spec2 := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID2, Input: &pb.ChaincodeInput{Args: args}}
655+
656+
cccid2 := ccprovider.NewCCContext(chainID, "example04", "0", "", false, nil, nil)
657+
658+
_, err = deploy(ctxt, cccid2, spec2, nextBlockNumber)
659+
nextBlockNumber++
660+
ccID2 := spec2.ChaincodeId.Name
661+
if err != nil {
662+
t.Fail()
663+
t.Logf("Error initializing chaincode %s(%s)", ccID2, err)
664+
theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1})
665+
theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2})
666+
return
667+
}
668+
669+
time.Sleep(time.Second)
670+
671+
// Invoke second chaincode passing the first chaincode's name as first param,
672+
// which will inturn invoke the first chaincode
673+
f = "invoke"
674+
cid := spec1.ChaincodeId.Name
675+
args = util.ToChaincodeArgs(f, cid, "e", "1")
676+
677+
spec2 = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID2, Input: &pb.ChaincodeInput{Args: args}}
678+
// Invoke chaincode
679+
var uuid string
680+
_, uuid, _, err = invoke(ctxt, chainID, spec2, nextBlockNumber)
681+
682+
if err != nil {
683+
t.Fail()
684+
t.Logf("Error invoking <%s>: %s", ccID2, err)
685+
theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1})
686+
theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2})
687+
return
688+
}
689+
690+
cccid1.TxID = uuid
691+
692+
// Check the state in the ledger
693+
err = checkFinalState(cccid1)
694+
if err != nil {
695+
t.Fail()
696+
t.Logf("Incorrect final state after transaction for <%s>: %s", ccID1, err)
697+
theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1})
698+
theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2})
699+
return
700+
}
701+
702+
theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1})
703+
theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2})
704+
705+
return
706+
}
707+
708+
// Test deploy of a transaction
709+
func TestExecuteDeployTransaction(t *testing.T) {
710+
//chaincoe is deployed as part of many tests. No need for a separate one for this
711+
t.Skip()
712+
chainID := util.GetTestChainID()
713+
714+
executeDeployTransaction(t, chainID, "example01", "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example01")
715+
}
716+
717+
// Test deploy of a transaction with a GOPATH with multiple elements
718+
func TestGopathExecuteDeployTransaction(t *testing.T) {
719+
//this is no longer critical as chaincode is assembled in the client side (SDK)
720+
t.Skip()
721+
chainID := util.GetTestChainID()
722+
723+
// add a trailing slash to GOPATH
724+
// and a couple of elements - it doesn't matter what they are
725+
os.Setenv("GOPATH", os.Getenv("GOPATH")+string(os.PathSeparator)+string(os.PathListSeparator)+"/tmp/foo"+string(os.PathListSeparator)+"/tmp/bar")
726+
executeDeployTransaction(t, chainID, "example01", "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example01")
727+
}
728+
637729
func TestExecuteInvokeTransaction(t *testing.T) {
638730

639731
testCases := []struct {
@@ -746,97 +838,6 @@ func TestChaincodeInvokeChaincode(t *testing.T) {
746838
closeListenerAndSleep(lis)
747839
}
748840

749-
func runChaincodeInvokeChaincode(t *testing.T, chainID string, _ string) (err error) {
750-
var ctxt = context.Background()
751-
752-
// Deploy first chaincode
753-
url1 := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02"
754-
755-
cID1 := &pb.ChaincodeID{Name: "example02", Path: url1, Version: "0"}
756-
f := "init"
757-
args := util.ToChaincodeArgs(f, "a", "100", "b", "200")
758-
759-
spec1 := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID1, Input: &pb.ChaincodeInput{Args: args}}
760-
761-
cccid1 := ccprovider.NewCCContext(chainID, "example02", "0", "", false, nil, nil)
762-
763-
var nextBlockNumber uint64
764-
765-
_, err = deploy(ctxt, cccid1, spec1, nextBlockNumber)
766-
nextBlockNumber++
767-
ccID1 := spec1.ChaincodeId.Name
768-
if err != nil {
769-
t.Fail()
770-
t.Logf("Error initializing chaincode %s(%s)", ccID1, err)
771-
theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1})
772-
return
773-
}
774-
775-
t.Logf("deployed chaincode_example02 got cID1:% s,\n ccID1:% s", cID1, ccID1)
776-
777-
time.Sleep(time.Second)
778-
779-
// Deploy second chaincode
780-
url2 := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example04"
781-
782-
cID2 := &pb.ChaincodeID{Name: "example04", Path: url2, Version: "0"}
783-
f = "init"
784-
args = util.ToChaincodeArgs(f, "e", "0")
785-
786-
spec2 := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID2, Input: &pb.ChaincodeInput{Args: args}}
787-
788-
cccid2 := ccprovider.NewCCContext(chainID, "example04", "0", "", false, nil, nil)
789-
790-
_, err = deploy(ctxt, cccid2, spec2, nextBlockNumber)
791-
nextBlockNumber++
792-
ccID2 := spec2.ChaincodeId.Name
793-
if err != nil {
794-
t.Fail()
795-
t.Logf("Error initializing chaincode %s(%s)", ccID2, err)
796-
theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1})
797-
theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2})
798-
return
799-
}
800-
801-
time.Sleep(time.Second)
802-
803-
// Invoke second chaincode passing the first chaincode's name as first param,
804-
// which will inturn invoke the first chaincode
805-
f = "invoke"
806-
cid := spec1.ChaincodeId.Name
807-
args = util.ToChaincodeArgs(f, cid, "e", "1")
808-
809-
spec2 = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID2, Input: &pb.ChaincodeInput{Args: args}}
810-
// Invoke chaincode
811-
var uuid string
812-
_, uuid, _, err = invoke(ctxt, chainID, spec2, nextBlockNumber)
813-
814-
if err != nil {
815-
t.Fail()
816-
t.Logf("Error invoking <%s>: %s", ccID2, err)
817-
theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1})
818-
theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2})
819-
return
820-
}
821-
822-
cccid1.TxID = uuid
823-
824-
// Check the state in the ledger
825-
err = checkFinalState(cccid1)
826-
if err != nil {
827-
t.Fail()
828-
t.Logf("Incorrect final state after transaction for <%s>: %s", ccID1, err)
829-
theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1})
830-
theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2})
831-
return
832-
}
833-
834-
theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1})
835-
theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2})
836-
837-
return
838-
}
839-
840841
// Test the execution of a chaincode that invokes another chaincode with wrong parameters. Should receive error from
841842
// from the called chaincode
842843
func TestChaincodeInvokeChaincodeErrorCase(t *testing.T) {
@@ -1647,6 +1648,23 @@ func TestChaincodeInitializeInitError(t *testing.T) {
16471648
}
16481649
}
16491650

1651+
func TestMain(m *testing.M) {
1652+
var err error
1653+
1654+
// setup the MSP manager so that we can sign/verify
1655+
mspMgrConfigDir := "../../msp/sampleconfig/"
1656+
msptesttools.LoadMSPSetupForTesting(mspMgrConfigDir)
1657+
signer, err = mspmgmt.GetLocalMSP().GetDefaultSigningIdentity()
1658+
if err != nil {
1659+
os.Exit(-1)
1660+
fmt.Print("Could not initialize msp/signer")
1661+
return
1662+
}
1663+
1664+
SetupTestConfig()
1665+
os.Exit(m.Run())
1666+
}
1667+
16501668
func deployChaincode(ctx context.Context, chaincodeCtx *ccprovider.CCContext, chaincodeType pb.ChaincodeSpec_Type, path string, args [][]byte, nextBlockNumber uint64) ([]byte, error) {
16511669

16521670
chaincodeSpec := &pb.ChaincodeSpec{
@@ -1670,23 +1688,6 @@ func deployChaincode(ctx context.Context, chaincodeCtx *ccprovider.CCContext, ch
16701688

16711689
var signer msp.SigningIdentity
16721690

1673-
func TestMain(m *testing.M) {
1674-
var err error
1675-
1676-
// setup the MSP manager so that we can sign/verify
1677-
mspMgrConfigDir := "../../msp/sampleconfig/"
1678-
msptesttools.LoadMSPSetupForTesting(mspMgrConfigDir)
1679-
signer, err = mspmgmt.GetLocalMSP().GetDefaultSigningIdentity()
1680-
if err != nil {
1681-
os.Exit(-1)
1682-
fmt.Print("Could not initialize msp/signer")
1683-
return
1684-
}
1685-
1686-
SetupTestConfig()
1687-
os.Exit(m.Run())
1688-
}
1689-
16901691
var rng *rand.Rand = rand.New(rand.NewSource(time.Now().UnixNano()))
16911692

16921693
func generateChaincodeName(chaincodeType pb.ChaincodeSpec_Type) string {

core/peer/peer.go

+18-6
Original file line numberDiff line numberDiff line change
@@ -256,21 +256,33 @@ func MockCreateChain(cid string) error {
256256
return err
257257
}
258258

259-
i := mockconfigtx.Initializer{
259+
chains.Lock()
260+
defer chains.Unlock()
261+
262+
// Here we need to mock also the policy manager
263+
// in order for the ACL to be checked
264+
initializer := mockconfigtx.Initializer{
260265
Resources: mockconfigtx.Resources{
261266
PolicyManagerVal: &mockpolicies.Manager{
262267
Policy: &mockpolicies.Policy{},
263268
},
264269
},
270+
PolicyProposerVal: &mockconfigtx.PolicyProposer{
271+
Transactional: mockconfigtx.Transactional{},
272+
},
273+
ValueProposerVal: &mockconfigtx.ValueProposer{
274+
Transactional: mockconfigtx.Transactional{},
275+
},
276+
}
277+
278+
manager := &mockconfigtx.Manager{
279+
Initializer: initializer,
265280
}
266281

267-
chains.Lock()
268-
defer chains.Unlock()
269282
chains.list[cid] = &chain{
270283
cs: &chainSupport{
271-
ledger: ledger,
272-
Manager: &mockconfigtx.Manager{Initializer: i},
273-
},
284+
Manager: manager,
285+
ledger: ledger},
274286
}
275287

276288
return nil

core/policy/mocks.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ type MockIdentityDeserializer struct {
7878
}
7979

8080
func (d *MockIdentityDeserializer) DeserializeIdentity(serializedIdentity []byte) (msp.Identity, error) {
81-
fmt.Printf("id : [%s], [%s]\n", string(serializedIdentity), string(d.Identity))
81+
fmt.Printf("[DeserializeIdentity] id : [%s], [%s]\n", string(serializedIdentity), string(d.Identity))
8282
if bytes.Equal(d.Identity, serializedIdentity) {
8383
fmt.Printf("GOT : [%s], [%s]\n", string(serializedIdentity), string(d.Identity))
8484
return &MockIdentity{identity: d.Identity, msg: d.Msg}, nil
@@ -93,6 +93,7 @@ type MockIdentity struct {
9393
}
9494

9595
func (id *MockIdentity) SatisfiesPrincipal(p *mspproto.MSPPrincipal) error {
96+
fmt.Printf("[SatisfiesPrincipal] id : [%s], [%s]\n", string(id.identity), string(p.Principal))
9697
if !bytes.Equal(id.identity, p.Principal) {
9798
return fmt.Errorf("Different identities [% x]!=[% x]", id.identity, p.Principal)
9899
}

core/policy/policy_test.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"testing"
2121

2222
"github.com/hyperledger/fabric/common/policies"
23+
"github.com/hyperledger/fabric/msp/mgmt"
2324
"github.com/hyperledger/fabric/protos/peer"
2425
"github.com/hyperledger/fabric/protos/utils"
2526
"github.com/stretchr/testify/assert"
@@ -73,11 +74,11 @@ func TestPolicyChecker(t *testing.T) {
7374

7475
// Alice is a member of the local MSP, policy check must succeed
7576
identityDeserializer.Msg = sProp.ProposalBytes
76-
err = pc.CheckPolicyNoChannel("member", sProp)
77+
err = pc.CheckPolicyNoChannel(mgmt.Members, sProp)
7778
assert.NoError(t, err)
7879

7980
sProp, _ = utils.MockSignedEndorserProposalOrPanic("A", &peer.ChaincodeSpec{}, []byte("Bob"), []byte("msg2"))
8081
// Bob is not a member of the local MSP, policy check must fail
81-
err = pc.CheckPolicyNoChannel("member", sProp)
82+
err = pc.CheckPolicyNoChannel(mgmt.Members, sProp)
8283
assert.Error(t, err)
8384
}

0 commit comments

Comments
 (0)