Skip to content

Commit

Permalink
ensure policies are uniq in endpoints
Browse files Browse the repository at this point in the history
  • Loading branch information
erossignon committed Sep 7, 2020
1 parent be3489e commit 6607a4b
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 78 deletions.
9 changes: 9 additions & 0 deletions packages/node-opcua-end2end-test/.mocharc.yml
@@ -0,0 +1,9 @@
require:
- ../../node_modules/source-map-support/register
- ../../node_modules/ts-node/register/transpile-only
recursive: tue
bail: true
extension:
- js
- ts
timeout: 500000
5 changes: 0 additions & 5 deletions packages/node-opcua-end2end-test/test/mocha.opts

This file was deleted.

54 changes: 54 additions & 0 deletions packages/node-opcua-end2end-test/test/test_verify_end_points.ts
@@ -0,0 +1,54 @@
import { OPCUAServer, OPCUAClient } from "node-opcua";
import * as should from "should";
const _should = should;
const port = 25400;

const describe = require("node-opcua-leak-detector").describeWithLeakDetector;
describe("Verifying Server Endpoint", () => {
let server: OPCUAServer;
let endpointUri: string = `opc.tcp://localhost:${port}`;
before(async () => {
server = new OPCUAServer({ port });
await server.initialize();
await server.start();
endpointUri = server.endpoints[0].endpointDescriptions()[0].endpointUrl!;
});

after(async () => {
await server.shutdown();
});

it("should not have duplicated policies", async () => {
// given a server
const client = OPCUAClient.create({ endpoint_must_exist: false });

await client.connect(endpointUri);

const endpointDescriptions = await client.getEndpoints();

try {
for (const e of endpointDescriptions) {
// console.log(e.toString());
const policyIds = e.userIdentityTokens!.map((a) => a.policyId!);

const counters: { [key: string]: number } = {};
policyIds?.forEach((a: string) => {
counters[a] = (counters[a] || 0) + 1;
});
const duplicatedPolicies = Object.entries(counters)
.filter(([k, v]) => v !== 1)
.map(([k, v]) => k);

if (duplicatedPolicies.length) {
console.log("duplicated policies", duplicatedPolicies);
}

duplicatedPolicies.should.eql([], "endpoint " + e.securityPolicyUri + " must not exhibit duplicated policies");
}
} catch (err) {
throw err;
} finally {
await client.disconnect();
}
});
});
2 changes: 1 addition & 1 deletion packages/node-opcua-end2end-test/tsconfig.json
@@ -1,7 +1,7 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
"rootDir": "source",
"rootDir": "test",
"outDir": "dist",
"composite": true
},
Expand Down
6 changes: 2 additions & 4 deletions packages/node-opcua-samples/bin/simple_server.js
Expand Up @@ -23,11 +23,9 @@ const {
install_optional_cpu_and_memory_usage_node,
build_address_space_for_conformance_testing,
RegisterServerMethod,
extractFullyQualifiedDomainName,
CreateMonitoredItemsResponse
extractFullyQualifiedDomainName
} = require("node-opcua");


Error.stackTraceLimit = Infinity;

function constructFilename(filename) {
Expand Down Expand Up @@ -144,7 +142,7 @@ const paths = envPaths(productUri);
const userPkiFolder = path.join(configFolder, "userPki");

const userCertificateManager = new OPCUACertificateManager({
automaticallyAcceptUnknownCertificate: false,
automaticallyAcceptUnknownCertificate: true,
name: "userPki",
rootFolder: userPkiFolder,
});
Expand Down
37 changes: 18 additions & 19 deletions packages/node-opcua-server/source/base_server.ts
Expand Up @@ -25,7 +25,7 @@ import { ServiceFault } from "node-opcua-service-secure-channel";
import { StatusCode, StatusCodes } from "node-opcua-status-code";
import { ApplicationDescriptionOptions } from "node-opcua-types";
import { EndpointDescription, GetEndpointsRequest } from "node-opcua-types";
import { OPCUAServerEndPoint, } from "./server_end_point";
import { OPCUAServerEndPoint } from "./server_end_point";
import { IChannelData } from "./i_channel_data";
import { ISocketData } from "./i_socket_data";

Expand Down Expand Up @@ -59,7 +59,7 @@ const default_server_info = {

discoveryProfileUri: "",

discoveryUrls: [],
discoveryUrls: []
};

function cleanupEndpoint(endpoint: OPCUAServerEndPoint) {
Expand Down Expand Up @@ -127,11 +127,9 @@ export class OPCUABaseServer extends OPCUASecureObject {

constructor(options?: OPCUABaseServerOptions) {
options = options || ({} as OPCUABaseServerOptions);
options.certificateFile =
options.certificateFile || constructFilename("certificates/server_selfsigned_cert_2048.pem");
options.certificateFile = options.certificateFile || constructFilename("certificates/server_selfsigned_cert_2048.pem");

options.privateKeyFile =
options.privateKeyFile || constructFilename("certificates/PKI/own/private/private_key.pem");
options.privateKeyFile = options.privateKeyFile || constructFilename("certificates/PKI/own/private/private_key.pem");

super(options);

Expand All @@ -156,7 +154,7 @@ export class OPCUABaseServer extends OPCUASecureObject {
this.serverCertificateManager =
options.serverCertificateManager ||
new OPCUACertificateManager({
name: "certificates",
name: "certificates"
});
}

Expand All @@ -174,20 +172,23 @@ export class OPCUABaseServer extends OPCUASecureObject {
assert(_.isArray(this.endpoints));
assert(this.endpoints.length > 0, "We need at least one end point");
callbackify(extractFullyQualifiedDomainName)((err: Error | null, fqdn: string) => {

const _on_new_channel = function(this: OPCUAServerEndPoint, channel: ServerSecureChannelLayer) {
const _on_new_channel = function (this: OPCUAServerEndPoint, channel: ServerSecureChannelLayer) {
self.emit("newChannel", channel, this);
};
const _on_close_channel = function (this: OPCUAServerEndPoint, channel: ServerSecureChannelLayer) {
self.emit("closeChannel", channel, this);
};

const _on_connectionRefused = function (this: OPCUAServerEndPoint, socketData: ISocketData) {
const _on_connectionRefused = function (this: OPCUAServerEndPoint, socketData: ISocketData) {
self.emit("connectionRefused", socketData, this);
}
const _on_openSecureChannelFailure = function(this: OPCUAServerEndPoint, socketData: ISocketData, channelData: IChannelData) {
};
const _on_openSecureChannelFailure = function (
this: OPCUAServerEndPoint,
socketData: ISocketData,
channelData: IChannelData
) {
self.emit("openSecureChannelFailure", socketData, channelData, this);
}
};

async.forEach(
this.endpoints,
Expand Down Expand Up @@ -253,7 +254,7 @@ export class OPCUABaseServer extends OPCUASecureObject {
(callback2: (err?: Error | null) => void) => {
endpoint.abruptlyInterruptChannels();
endpoint.shutdown(callback2);
},
}
// xx (callback2: (err?: Error| null) => void) => {
// xx endpoint.restoreConnection(callback2);
// xx }
Expand Down Expand Up @@ -415,9 +416,7 @@ export class OPCUABaseServer extends OPCUASecureObject {

response.endpoints = server._get_endpoints();

response.endpoints = response.endpoints.filter(
(endpoint: EndpointDescription) => !(endpoint as any).restricted
);
response.endpoints = response.endpoints.filter((endpoint: EndpointDescription) => !(endpoint as any).restricted);

// apply filters
if (request.profileUris && request.profileUris.length > 0) {
Expand Down Expand Up @@ -473,12 +472,12 @@ export class OPCUABaseServer extends OPCUASecureObject {
discoveryProfileUri: applicationDescription.discoveryProfileUri,
discoveryUrls: applicationDescription.discoveryUrls,
gatewayServerUri: applicationDescription.gatewayServerUri,
productUri: applicationDescription.productUri,
productUri: applicationDescription.productUri
});
}

const response = new FindServersResponse({
servers: servers.map(adapt),
servers: servers.map(adapt)
});

channel.send_response("MSG", response, message, emptyCallback);
Expand Down
68 changes: 19 additions & 49 deletions packages/node-opcua-server/source/server_end_point.ts
Expand Up @@ -22,7 +22,7 @@ import {
ServerSecureChannelLayer,
ServerSecureChannelParent,
toURI,
AsymmetricAlgorithmSecurityHeader,
AsymmetricAlgorithmSecurityHeader
} from "node-opcua-secure-channel";
import { UserTokenType } from "node-opcua-service-endpoints";
import { EndpointDescription } from "node-opcua-service-endpoints";
Expand All @@ -46,7 +46,7 @@ function extractSocketData(socket: net.Socket, reason: string): ISocketData {
remoteAddress,
remoteFamily,
remotePort,
timestamp: new Date(),
timestamp: new Date()
};
return data;
}
Expand All @@ -61,7 +61,7 @@ function extractChannelData(channel: ServerSecureChannelLayer): IChannelData {
securityMode,
securityPolicy,
timeout,
transactionsCount,
transactionsCount
} = channel;

const channelData: IChannelData = {
Expand All @@ -73,7 +73,7 @@ function extractChannelData(channel: ServerSecureChannelLayer): IChannelData {
securityMode,
securityPolicy,
timeout,
transactionsCount,
transactionsCount
};
return channelData;
}
Expand Down Expand Up @@ -390,7 +390,7 @@ export class OPCUAServerEndPoint extends EventEmitter implements ServerSecureCha
allowUnsecurePassword: options.allowUnsecurePassword,
resourcePath: options.resourcePath,

restricted: !!options.restricted,
restricted: !!options.restricted
})
);
}
Expand Down Expand Up @@ -629,9 +629,7 @@ export class OPCUAServerEndPoint extends EventEmitter implements ServerSecureCha
// istanbul ignore next
if (doDebug) {
this._dump_statistics();
debugLog(
"server connected with : " + (socket as any).remoteAddress + ":" + (socket as any).remotePort
);
debugLog("server connected with : " + (socket as any).remoteAddress + ":" + (socket as any).remotePort);
}
})
.on("close", () => {
Expand Down Expand Up @@ -690,7 +688,7 @@ export class OPCUAServerEndPoint extends EventEmitter implements ServerSecureCha
defaultSecureTokenLifetime: this.defaultSecureTokenLifetime,
// objectFactory: this.objectFactory,
parent: this,
timeout: this.timeout,
timeout: this.timeout
});

socket.resume();
Expand Down Expand Up @@ -993,7 +991,7 @@ function _makeEndpointDescription(options: MakeEndpointDescriptionOptions): Endp

issuedTokenType: null,
issuerEndpointUrl: null,
securityPolicyUri: null,
securityPolicyUri: null
});
}

Expand All @@ -1003,16 +1001,16 @@ function _makeEndpointDescription(options: MakeEndpointDescriptionOptions): Endp

issuedTokenType: null,
issuerEndpointUrl: null,
securityPolicyUri: SecurityPolicy.Basic256,
securityPolicyUri: SecurityPolicy.Basic256
});

userIdentityTokens.push({
policyId: "username_basic128",
policyId: "username_basic128Rsa15",
tokenType: UserTokenType.UserName,

issuedTokenType: null,
issuerEndpointUrl: null,
securityPolicyUri: SecurityPolicy.Basic128Rsa15,
securityPolicyUri: SecurityPolicy.Basic128Rsa15
});

userIdentityTokens.push({
Expand All @@ -1021,16 +1019,7 @@ function _makeEndpointDescription(options: MakeEndpointDescriptionOptions): Endp

issuedTokenType: null,
issuerEndpointUrl: null,
securityPolicyUri: SecurityPolicy.Basic256Sha256,
});

userIdentityTokens.push({
policyId: "certificate_basic256Sha256",
tokenType: UserTokenType.Certificate,

issuedTokenType: null,
issuerEndpointUrl: null,
securityPolicyUri: SecurityPolicy.Basic256Sha256,
securityPolicyUri: SecurityPolicy.Basic256Sha256
});

// X509
Expand All @@ -1040,34 +1029,15 @@ function _makeEndpointDescription(options: MakeEndpointDescriptionOptions): Endp

issuedTokenType: null,
issuerEndpointUrl: null,
securityPolicyUri: SecurityPolicy.Basic256,
});

userIdentityTokens.push({
policyId: "certificate_basic128",
tokenType: UserTokenType.UserName,

issuedTokenType: null,
issuerEndpointUrl: null,
securityPolicyUri: SecurityPolicy.Basic128Rsa15,
});

userIdentityTokens.push({
policyId: "certificate_basic256Sha256",
tokenType: UserTokenType.UserName,

issuedTokenType: null,
issuerEndpointUrl: null,
securityPolicyUri: SecurityPolicy.Basic256Sha256,
securityPolicyUri: SecurityPolicy.Basic256
});

userIdentityTokens.push({
policyId: "certificate_basic256Sha256",
tokenType: UserTokenType.Certificate,

issuedTokenType: null,
issuerEndpointUrl: null,
securityPolicyUri: SecurityPolicy.Basic256Sha256,
securityPolicyUri: SecurityPolicy.Basic256Sha256
});
} else {
// note:
Expand All @@ -1080,7 +1050,7 @@ function _makeEndpointDescription(options: MakeEndpointDescriptionOptions): Endp

issuedTokenType: null,
issuerEndpointUrl: null,
securityPolicyUri: null,
securityPolicyUri: null
});

userIdentityTokens.push({
Expand All @@ -1089,7 +1059,7 @@ function _makeEndpointDescription(options: MakeEndpointDescriptionOptions): Endp

issuedTokenType: null,
issuerEndpointUrl: null,
securityPolicyUri: null,
securityPolicyUri: null
});
}

Expand All @@ -1100,7 +1070,7 @@ function _makeEndpointDescription(options: MakeEndpointDescriptionOptions): Endp

issuedTokenType: null,
issuerEndpointUrl: null,
securityPolicyUri: null,
securityPolicyUri: null
});
}

Expand All @@ -1116,7 +1086,7 @@ function _makeEndpointDescription(options: MakeEndpointDescriptionOptions): Endp
userIdentityTokens,

securityLevel: options.securityLevel,
transportProfileUri: default_transportProfileUri,
transportProfileUri: default_transportProfileUri
}) as EndpointDescriptionEx;

(endpoint as any).__defineGetter__("endpointUrl", () => {
Expand Down Expand Up @@ -1157,5 +1127,5 @@ const defaultSecurityPolicies = [
SecurityPolicy.Basic128Rsa15,
SecurityPolicy.Basic256,
// xx UNUSED!! SecurityPolicy.Basic256Rsa15,
SecurityPolicy.Basic256Sha256,
SecurityPolicy.Basic256Sha256
];

0 comments on commit 6607a4b

Please sign in to comment.