From 061ef6af57f79438080b989eab35e6d52935db61 Mon Sep 17 00:00:00 2001 From: Chongxin Luo Date: Tue, 24 Sep 2019 11:36:24 -0400 Subject: [PATCH] [FAB-16118] Add IT for MSP unauthorized Peer Added integration test for MSP identity of unauthorized peer to replace old behavior test. FAB-16118 #done Change-Id: I44e731dd394b3ed1968b0bc42f93e595bee1f47a Signed-off-by: Chongxin Luo --- integration/msp/msp_suite_test.go | 49 ++++++++ integration/msp/msp_test.go | 195 ++++++++++++++++++++++++++++++ integration/ports.go | 3 +- 3 files changed, 246 insertions(+), 1 deletion(-) create mode 100644 integration/msp/msp_suite_test.go create mode 100644 integration/msp/msp_test.go diff --git a/integration/msp/msp_suite_test.go b/integration/msp/msp_suite_test.go new file mode 100644 index 00000000000..fc5c5b43dbf --- /dev/null +++ b/integration/msp/msp_suite_test.go @@ -0,0 +1,49 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package msp + +import ( + "encoding/json" + "testing" + + "github.com/hyperledger/fabric/integration" + "github.com/hyperledger/fabric/integration/nwo" + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" +) + +func TestMSP(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "MSP Suite") +} + +var ( + buildServer *nwo.BuildServer + components *nwo.Components +) + +var _ = SynchronizedBeforeSuite(func() []byte { + buildServer = nwo.NewBuildServer() + buildServer.Serve() + + components = buildServer.Components() + payload, err := json.Marshal(components) + Expect(err).NotTo(HaveOccurred()) + return payload +}, func(payload []byte) { + err := json.Unmarshal(payload, &components) + Expect(err).NotTo(HaveOccurred()) +}) + +var _ = SynchronizedAfterSuite(func() { +}, func() { + buildServer.Shutdown() +}) + +func StartPort() int { + return integration.MSPPort.StartPortForNode() +} diff --git a/integration/msp/msp_test.go b/integration/msp/msp_test.go new file mode 100644 index 00000000000..4d66ea1666a --- /dev/null +++ b/integration/msp/msp_test.go @@ -0,0 +1,195 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package msp + +import ( + "fmt" + "io" + "io/ioutil" + "os" + "path/filepath" + "syscall" + + docker "github.com/fsouza/go-dockerclient" + "github.com/hyperledger/fabric/integration/nwo" + "github.com/hyperledger/fabric/integration/nwo/commands" + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + "github.com/onsi/gomega/gbytes" + "github.com/onsi/gomega/gexec" + "github.com/tedsuo/ifrit" +) + +var _ = Describe("MSP identity test on a network with mutual TLS required", func() { + var ( + client *docker.Client + tempDir string + network *nwo.Network + process ifrit.Process + ) + + BeforeEach(func() { + var err error + tempDir, err = ioutil.TempDir("", "msp") + Expect(err).NotTo(HaveOccurred()) + + client, err = docker.NewClientFromEnv() + Expect(err).NotTo(HaveOccurred()) + + network = nwo.New(nwo.BasicSolo(), tempDir, client, StartPort(), components) + }) + + AfterEach(func() { + // Shutdown processes and cleanup + process.Signal(syscall.SIGTERM) + Eventually(process.Wait(), network.EventuallyTimeout).Should(Receive()) + + if network != nil { + network.Cleanup() + } + os.RemoveAll(tempDir) + }) + + It("invokes chaincode on a peer that does not have a valid endorser identity", func() { + By("setting TLS ClientAuthRequired to be true for all peers and orderers") + network.ClientAuthRequired = true + + network.GenerateConfigTree() + network.Bootstrap() + + By("starting all processes for fabric") + networkRunner := network.NetworkGroupRunner() + process = ifrit.Invoke(networkRunner) + Eventually(process.Ready(), network.EventuallyTimeout).Should(BeClosed()) + + peer := network.Peers[0] + orderer := network.Orderer("orderer") + + By("creating and joining channels") + network.CreateAndJoinChannels(orderer) + By("enabling new lifecycle capabilities") + nwo.EnableCapabilities(network, "testchannel", "Application", "V2_0", orderer, network.Peer("Org1", "peer1"), network.Peer("Org2", "peer1")) + + chaincode := nwo.Chaincode{ + Name: "mycc", + Version: "0.0", + Path: "github.com/hyperledger/fabric/integration/chaincode/simple/cmd", + Lang: "golang", + PackageFile: filepath.Join(tempDir, "simplecc.tar.gz"), + Ctor: `{"Args":["init","a","100","b","200"]}`, + SignaturePolicy: `OR ('Org1MSP.peer', 'Org2MSP.peer')`, + Sequence: "1", + InitRequired: true, + Label: "my_simple_chaincode", + } + + By("deploying the chaincode") + nwo.DeployChaincode(network, "testchannel", orderer, chaincode) + + By("querying and invoking chaincode with mutual TLS enabled") + RunQueryInvokeQuery(network, orderer, peer, 100) + + By("replacing org2peer0's identity with a client identity") + org2Peer0 := network.Peer("Org2", "peer0") + org2Peer0MSPDir := network.PeerLocalMSPDir(org2Peer0) + org2User1MSPDir := network.PeerUserMSPDir(org2Peer0, "User1") + + _, err := copyFile(filepath.Join(org2User1MSPDir, "signcerts", "User1@org2.example.com-cert.pem"), filepath.Join(org2Peer0MSPDir, "signcerts", "peer0.org2.example.com-cert.pem")) + Expect(err).NotTo(HaveOccurred()) + _, err = copyFile(filepath.Join(org2User1MSPDir, "keystore", "priv_sk"), filepath.Join(org2Peer0MSPDir, "keystore", "priv_sk")) + Expect(err).NotTo(HaveOccurred()) + + By("restarting all fabric processes to reload MSP identities") + process.Signal(syscall.SIGTERM) + Eventually(process.Wait(), network.EventuallyTimeout).Should(Receive()) + networkRunner = network.NetworkGroupRunner() + process = ifrit.Invoke(networkRunner) + Eventually(process.Ready(), network.EventuallyTimeout).Should(BeClosed()) + + By("attempting to invoke chaincode on a peer that does not have a valid endorser identity") + sess, err := network.PeerUserSession(peer, "User1", commands.ChaincodeInvoke{ + ChannelID: "testchannel", + Orderer: network.OrdererAddress(orderer, nwo.ListenPort), + Name: "mycc", + Ctor: `{"Args":["invoke","a","b","10"]}`, + PeerAddresses: []string{ + network.PeerAddress(network.Peer("Org2", "peer0"), nwo.ListenPort), + }, + WaitForEvent: true, + ClientAuth: network.ClientAuthRequired, + }) + Expect(err).NotTo(HaveOccurred()) + Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(1)) + Expect(sess.Err).To(gbytes.Say(`(ENDORSEMENT_POLICY_FAILURE)`)) + + By("reverifying the channel was not affected by the unauthorized endorsement") + sess, err = network.PeerUserSession(peer, "User1", commands.ChaincodeQuery{ + ChannelID: "testchannel", + Name: "mycc", + Ctor: `{"Args":["query","a"]}`, + }) + Expect(err).NotTo(HaveOccurred()) + Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(0)) + Expect(sess).To(gbytes.Say("90")) + }) +}) + +func RunQueryInvokeQuery(n *nwo.Network, orderer *nwo.Orderer, peer *nwo.Peer, initialQueryResult int) { + sess, err := n.PeerUserSession(peer, "User1", commands.ChaincodeQuery{ + ChannelID: "testchannel", + Name: "mycc", + Ctor: `{"Args":["query","a"]}`, + }) + Expect(err).NotTo(HaveOccurred()) + Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit(0)) + Expect(sess).To(gbytes.Say(fmt.Sprint(initialQueryResult))) + + sess, err = n.PeerUserSession(peer, "User1", commands.ChaincodeInvoke{ + ChannelID: "testchannel", + Orderer: n.OrdererAddress(orderer, nwo.ListenPort), + Name: "mycc", + Ctor: `{"Args":["invoke","a","b","10"]}`, + PeerAddresses: []string{ + n.PeerAddress(n.Peer("Org1", "peer1"), nwo.ListenPort), + n.PeerAddress(n.Peer("Org2", "peer1"), nwo.ListenPort), + }, + WaitForEvent: true, + ClientAuth: n.ClientAuthRequired, + }) + Expect(err).NotTo(HaveOccurred()) + Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit(0)) + Expect(sess.Err).To(gbytes.Say("Chaincode invoke successful. result: status:200")) + + sess, err = n.PeerUserSession(peer, "User1", commands.ChaincodeQuery{ + ChannelID: "testchannel", + Name: "mycc", + Ctor: `{"Args":["query","a"]}`, + }) + Expect(err).NotTo(HaveOccurred()) + Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit(0)) + Expect(sess).To(gbytes.Say(fmt.Sprint(initialQueryResult - 10))) +} + +func copyFile(src, dst string) (int64, error) { + source, err := os.Open(src) + if err != nil { + return 0, err + } + defer source.Close() + + err = os.Remove(dst) + if err != nil { + return 0, err + } + destination, err := os.Create(dst) + if err != nil { + return 0, err + } + defer destination.Close() + nBytes, err := io.Copy(destination, source) + return nBytes, err +} diff --git a/integration/ports.go b/integration/ports.go index ccb63638667..9816e0ea8dc 100644 --- a/integration/ports.go +++ b/integration/ports.go @@ -26,14 +26,15 @@ const ( DiscoveryBasePort TestPortRange = basePort + portsPerSuite*iota E2EBasePort GossipBasePort + IdemixBasePort LedgerPort LifecyclePort + MSPPort NWOBasePort PluggableBasePort PrivateDataBasePort RaftBasePort SBEBasePort - IdemixBasePort ) // On linux, the default ephemeral port range is 32768-60999 and can be