Skip to content

Commit

Permalink
fix(dast): ccp, sshconfig missing
Browse files Browse the repository at this point in the history
Primary Changes
----------------
1. Fix the issue on plugin-ledger-connector-fabric that throws an error when
there is no sshConfig available.

Fixes #3671

Signed-off-by: raynato.c.pedrajeta <raynato.c.pedrajeta@accenture.com>
  • Loading branch information
raynatopedrajeta committed Dec 26, 2024
1 parent c66a1c6 commit 4048f3e
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 92 deletions.
5 changes: 2 additions & 3 deletions .github/workflows/.dast-nuclei-cmd-api-server.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ jobs:
run: |
echo https://localhost:4000/ > urls.txt
{
echo https://localhost:4000/api/v1/api-server/healthcheck
echo https://localhost:4000/api/v1/plugins/@hyperledger/cactus-plugin-consortium-manual/node/jws
echo https://localhost:4000/api/v1/plugins/@hyperledger/cactus-plugin-consortium-manual/consortium/jws
echo https://localhost:4000/api/v1/plugins/@hyperledger/cactus-plugin-consortium-manual/get-prometheus-exporter-metrics
Expand Down Expand Up @@ -85,7 +84,7 @@ jobs:
run: jq '.plugins += [{ "packageName":"@hyperledger/cactus-plugin-keychain-memory","type":"org.hyperledger.cactus.plugin_import_type.LOCAL","action":"org.hyperledger.cactus.plugin_import_action.INSTALL","options":{"packageSrc":"/home/runner/work/cacti/cacti/packages/cactus-plugin-keychain-memory/","instanceId":"0daacd05-d1cd-4eab-9332-4ad1aff4b909","keychainId":"d29d728e-eaa0-4e2d-b187-d132242b0d9a"}}]' .config.json > .config2.json && mv .config2.json .config.json

- name: Install Fabric connector into the API server
run: jq '.plugins += [{ "packageName":"@hyperledger/cactus-plugin-ledger-connector-fabric", "type":"org.hyperledger.cactus.plugin_import_type.LOCAL", "action":"org.hyperledger.cactus.plugin_import_action.INSTALL", "options":{ "packageSrc":"/home/runner/work/cacti/cacti/packages/cactus-plugin-ledger-connector-fabric/", "instanceId":"some-unique-fabric-connector-instance-id", "peerBinary":"/fabric-samples/bin/peer", "connectionProfile":"{}", "dockerBinary":"usr/local/bin/docker","cliContainerEnv":{"CORE_PEER_LOCALMSPID":"Org1MSP","CORE_PEER_ADDRESS":"peer0.org1.example.com:7051","CORE_PEER_MSPCONFIGPATH":"/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp","CORE_PEER_TLS_ROOTCERT_FILE":"/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt","ORDERER_TLS_ROOTCERT_FILE":"/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem"},"discoveryOptions":{"enabled":true,"asLocalhost":true}}}] ' .config.json > .config2.json && mv .config2.json .config.json
run: jq '.plugins += [{ "packageName":"@hyperledger/cactus-plugin-ledger-connector-fabric", "type":"org.hyperledger.cactus.plugin_import_type.LOCAL", "action":"org.hyperledger.cactus.plugin_import_action.INSTALL", "options":{ "packageSrc":"/home/runner/work/cacti/cacti/packages/cactus-plugin-ledger-connector-fabric/", "instanceId":"some-unique-fabric-connector-instance-id", "peerBinary":"/fabric-samples/bin/peer", "connectionProfile":"{}", "connectionProfile":"{}", "dockerBinary":"usr/local/bin/docker","cliContainerEnv":{"CORE_PEER_LOCALMSPID":"Org1MSP","CORE_PEER_ADDRESS":"peer0.org1.example.com:7051","CORE_PEER_MSPCONFIGPATH":"/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp","CORE_PEER_TLS_ROOTCERT_FILE":"/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt","ORDERER_TLS_ROOTCERT_FILE":"/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem"},"discoveryOptions":{"enabled":true,"asLocalhost":true}}}] ' .config.json > .config2.json && mv .config2.json .config.json

- name: Install Besu connector into the API server
run: jq '.plugins += [{"packageName":"@hyperledger/cactus-plugin-ledger-connector-besu","type":"org.hyperledger.cactus.plugin_import_type.LOCAL","action":"org.hyperledger.cactus.plugin_import_action.INSTALL","options":{"packageSrc":"/home/runner/work/cacti/cacti/packages/cactus-plugin-ledger-connector-besu/", "rpcApiHttpHost":"http://127.0.0.1:8545", "rpcApiWsHost":"ws://127.0.0.1:8546", "instanceId":"some-unique-besu-connector-instance-id"}}]' .config.json > .config2.json && mv .config2.json .config.json
Expand Down Expand Up @@ -116,7 +115,7 @@ jobs:
start: yarn start:api-server
command: "nuclei -version"
command-windows: echo "The project build is not supported on the Windows operating system. Please use Linux or macOS"
wait-on: "https://localhost:4000/api/v1/api-server/healthcheck"
wait-on: "https://localhost:4000/api/v1/plugins/@hyperledger/cactus-plugin-consortium-manual/node/jws"
# wait for 10 minutes for the server to respond
wait-on-timeout: 120

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import temp from "temp";
import fs from "fs/promises";

import {
Config as SshConfig,
NodeSSH,
SSHExecCommandOptions,
SSHExecCommandResponse,
Expand Down Expand Up @@ -36,7 +35,6 @@ export interface IDeployContractGoSourceImplFabricV256Context {
readonly log: Logger;
readonly className: string;
readonly dockerBinary: string;
readonly sshConfig: SshConfig;
readonly opts: IPluginLedgerConnectorFabricOptions;
}

Expand All @@ -55,7 +53,7 @@ export async function deployContractGoSourceImplFabricV256(
ctx.opts.cliContainerGoPath || K_DEFAULT_CLI_CONTAINER_GO_PATH;

const ssh = new NodeSSH();
await ssh.connect(ctx.sshConfig);
await ssh.connect(ctx.opts.sshConfig);
log.debug(`SSH connection OK`);

try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,6 @@ import {
formatCactiFullBlockResponse,
formatCactiTransactionsBlockResponse,
} from "./get-block/cacti-block-formatters";

import { GetBlockEndpointV1 } from "./get-block/get-block-endpoint-v1";
import { GetChainInfoEndpointV1 } from "./get-chain-info/get-chain-info-endpoint-v1";
import { querySystemChainCode } from "./common/query-system-chain-code";
Expand All @@ -159,17 +158,17 @@ import {
} from "./common/utils";
import { findAndReplaceFabricLoggingSpec } from "./common/find-and-replace-fabric-logging-spec";
import { deployContractGoSourceImplFabricV256 } from "./deploy-contract-go-source/deploy-contract-go-source-impl-fabric-v2-5-6";
import { Observable, ReplaySubject } from "rxjs";

const { loadFromConfig } = require("fabric-network/lib/impl/ccp/networkconfig");
assertFabricFunctionIsAvailable(loadFromConfig, "loadFromConfig");
import { Observable, ReplaySubject } from "rxjs";


export interface IRunTxReqWithTxId {
request: RunTransactionRequest;
transactionId: string;
timestamp: Date;
}

/**
* Constant value holding the default $GOPATH in the Fabric CLI container as
* observed on fabric deployments that are produced by the official examples
Expand Down Expand Up @@ -197,11 +196,9 @@ export interface IPluginLedgerConnectorFabricOptions
cliContainerGoPath?: string;
cliContainerEnv: NodeJS.ProcessEnv;
pluginRegistry: PluginRegistry;
sshConfig?: SshConfig;
sshConfigB64?: string;
sshConfig: SshConfig;
readonly sshDebugOn?: boolean;
connectionProfile?: ConnectionProfile;
connectionProfileB64?: string;
connectionProfile: ConnectionProfile;
prometheusExporter?: PrometheusExporter;
discoveryOptions?: GatewayDiscoveryOptions;
eventHandlerOptions?: GatewayEventHandlerOptions;
Expand Down Expand Up @@ -229,8 +226,6 @@ export class PluginLedgerConnectorFabric
private readonly peerBinary: string;
private readonly goBinary: string;
private readonly cliContainerGoPath: string;
private readonly sshConfig: SshConfig;
private readonly connectionProfile: ConnectionProfile;
public prometheusExporter: PrometheusExporter;
private endpoints: IWebServiceEndpoint[] | undefined;
private readonly secureIdentity: SecureIdentityProviders;
Expand All @@ -254,6 +249,7 @@ export class PluginLedgerConnectorFabric
Checks.truthy(opts.instanceId, `${fnTag} options.instanceId`);
Checks.truthy(opts.peerBinary, `${fnTag} options.peerBinary`);
Checks.truthy(opts.pluginRegistry, `${fnTag} options.pluginRegistry`);
Checks.truthy(opts.connectionProfile, `${fnTag} options.connectionProfile`);
this.prometheusExporter =
opts.prometheusExporter ||
new PrometheusExporter({ pollingIntervalInMin: 1 });
Expand Down Expand Up @@ -289,33 +285,9 @@ export class PluginLedgerConnectorFabric
});
this.certStore = new CertDatastore(opts.pluginRegistry);

if (this.opts.connectionProfile) {
this.connectionProfile = this.opts.connectionProfile;
} else if (this.opts.connectionProfileB64) {
const connectionProfileBuffer = Buffer.from(
this.opts.connectionProfileB64,
"base64",
);
const connectionProfileString = connectionProfileBuffer.toString("utf-8");
this.connectionProfile = JSON.parse(connectionProfileString);
} else {
throw new Error(
"Cannot instantiate Fabric connector without connection profile.",
);
}

this.sshDebugOn = opts.sshDebugOn === true;
if (this.opts.sshConfig) {
this.sshConfig = this.opts.sshConfig;
} else if (this.opts.sshConfigB64) {
const sshConfigBuffer = Buffer.from(this.opts.sshConfigB64, "base64");
const sshConfigString = sshConfigBuffer.toString("utf-8");
this.sshConfig = JSON.parse(sshConfigString);
} else {
throw new Error("Cannot instantiate Fabric connector without SSH config");
}
if (this.sshDebugOn) {
this.sshConfig = this.enableSshDebugLogs(this.sshConfig);
this.opts.sshConfig = this.enableSshDebugLogs(this.opts.sshConfig);
}

this.signCallback = opts.signCallback;
Expand Down Expand Up @@ -348,10 +320,6 @@ export class PluginLedgerConnectorFabric
return `@hyperledger/cactus-plugin-ledger-connector-fabric`;
}

public getTxSubjectObservable(): Observable<IRunTxReqWithTxId> {
return this.txSubject.asObservable();
}

public async onPluginInit(): Promise<unknown> {
return;
}
Expand All @@ -366,6 +334,10 @@ export class PluginLedgerConnectorFabric
return consensusHasTransactionFinality(currentConsensusAlgorithmFamily);
}

public getTxSubjectObservable(): Observable<IRunTxReqWithTxId> {
return this.txSubject.asObservable();
}

private enableSshDebugLogs(cfg: SshConfig): SshConfig {
const fnTag = `${this.className}#decorateSshConfigWithLogger()`;
Checks.truthy(cfg, `${fnTag} cfg must be truthy.`);
Expand All @@ -382,6 +354,7 @@ export class PluginLedgerConnectorFabric
sshCmdOptions: SSHExecCommandOptions,
): Promise<SSHExecCommandResponse> {
this.log.debug(`${label} CMD: ${cmd}`);

const cmdRes = await ssh.execCommand(cmd, sshCmdOptions);
this.log.debug(`${label} CMD Response .code: %o`, cmdRes.code);
this.log.debug(`${label} CMD Response .signal: %o`, cmdRes.signal);
Expand All @@ -401,11 +374,11 @@ export class PluginLedgerConnectorFabric
req: DeployContractV1Request,
): Promise<DeployContractV1Response> {
const fnTag = `${this.className}#deployContract()`;
const { log } = this;
const { log, opts } = this;

const ssh = new NodeSSH();
this.log.debug(`${fnTag} Establishing SSH connection to peer...`);
await ssh.connect(this.sshConfig);
await ssh.connect(opts.sshConfig);
this.log.debug(`${fnTag} Established SSH connection to peer OK.`);

if (req.collectionsConfigFile) {
Expand Down Expand Up @@ -706,7 +679,6 @@ export class PluginLedgerConnectorFabric
log,
opts: this.opts,
dockerBinary: this.dockerBinary,
sshConfig: this.sshConfig,
className: this.className,
};
return deployContractGoSourceImplFabricV256(ctx, req);
Expand Down Expand Up @@ -951,7 +923,7 @@ export class PluginLedgerConnectorFabric
return createGateway({
logLevel: this.opts.logLevel,
pluginRegistry: this.opts.pluginRegistry,
defaultConnectionProfile: this.connectionProfile,
defaultConnectionProfile: this.opts.connectionProfile,
defaultDiscoveryOptions: this.opts.discoveryOptions || {
enabled: true,
asLocalhost: true,
Expand All @@ -976,8 +948,7 @@ export class PluginLedgerConnectorFabric
protected async createGatewayLegacy(
signingCredential: FabricSigningCredential,
): Promise<Gateway> {
const { eventHandlerOptions: eho } = this.opts;
const connectionProfile = this.connectionProfile;
const { connectionProfile, eventHandlerOptions: eho } = this.opts;

const iType = signingCredential.type || FabricSigningCredentialType.X509;

Expand Down Expand Up @@ -1191,7 +1162,6 @@ export class PluginLedgerConnectorFabric
): Promise<RunTransactionResponse> {
const fnTag = `${this.className}#transact()`;
this.log.debug("%s ENTER", fnTag);

const {
channelName,
contractName,
Expand Down Expand Up @@ -1261,7 +1231,6 @@ export class PluginLedgerConnectorFabric
const transactionProposal = await contract.createTransaction(fnName);
transactionProposal.setEndorsingPeers(endorsingTargets);
out = await transactionProposal.setTransient(transientMap).submit();
transactionId = transactionProposal.getTransactionId();
break;
}
default: {
Expand All @@ -1270,17 +1239,6 @@ export class PluginLedgerConnectorFabric
}
}

// create IRunTxReqWithTxId for transaction monitoring
const receiptData: IRunTxReqWithTxId = {
request: req,
transactionId: transactionId == "" ? uuidv4() : transactionId,
timestamp: new Date(),
};
this.log.debug(
`IRunTxReqWithTxId created with ID: ${receiptData.transactionId}`,
);
this.txSubject.next(receiptData);

const res: RunTransactionResponse = {
functionOutput: this.convertToTransactionResponseType(
out,
Expand Down Expand Up @@ -1319,7 +1277,7 @@ export class PluginLedgerConnectorFabric
public async createCaClient(caId: string): Promise<FabricCAServices> {
const fnTag = `${this.className}#createCaClient()`;
try {
const ccp = this.connectionProfile;
const ccp = this.opts.connectionProfile;
if (!ccp.certificateAuthorities) {
throw new Error(`${fnTag} conn. profile certificateAuthorities falsy.`);
}
Expand Down Expand Up @@ -1724,7 +1682,7 @@ export class PluginLedgerConnectorFabric
this.log.debug("Create Fabric Client without a signer with ID", clientId);
const client = new Client(clientId);
// Use fabric SDK methods for parsing connection profile into Client structure
await loadFromConfig(client, this.connectionProfile);
await loadFromConfig(client, this.opts.connectionProfile);

// Create user
const user = User.createUser("", "", signerMspID, signerCertificate);
Expand Down Expand Up @@ -1937,4 +1895,4 @@ export class PluginLedgerConnectorFabric
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -251,32 +251,6 @@ describe(testCase, () => {
}

{
const connectionProfileString = JSON.stringify(connectionProfile);
const connectionProfileB64Buffer = Buffer.from(connectionProfileString);
const sshConfigString = JSON.stringify(sshConfig);
const connectionProfileB64 =
connectionProfileB64Buffer.toString("base64");
const sshConfigB64Buffer = Buffer.from(sshConfigString);
const sshConfigB64 = sshConfigB64Buffer.toString("base64");
const pluginOptionsSerialized: IPluginLedgerConnectorFabricOptions = {
instanceId: uuidv4(),
pluginRegistry,
sshConfigB64,
cliContainerEnv: {},
peerBinary: "/fabric-samples/bin/peer",
logLevel,
connectionProfileB64,
discoveryOptions,
eventHandlerOptions: {
strategy: DefaultEventHandlerStrategy.NetworkScopeAllfortx,
commitTimeout: 300,
},
};
const pluginWithSerializedInputs = new PluginLedgerConnectorFabric(
pluginOptionsSerialized,
);
await pluginWithSerializedInputs.getOrCreateWebServices();
await pluginWithSerializedInputs.registerWebServices(expressApp);
const req: RunTransactionRequest = {
signingCredential,
gatewayOptions: {
Expand Down

0 comments on commit 4048f3e

Please sign in to comment.