node-opcua-server 2.76.1 → 2.76.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/dist/base_server.d.ts +110 -110
  2. package/dist/base_server.js +473 -473
  3. package/dist/factory.d.ts +12 -12
  4. package/dist/factory.js +23 -23
  5. package/dist/filter/check_where_clause_on_address_space.d.ts +3 -3
  6. package/dist/filter/check_where_clause_on_address_space.js +22 -22
  7. package/dist/filter/extract_event_fields.d.ts +10 -10
  8. package/dist/filter/extract_event_fields.js +17 -17
  9. package/dist/helper.d.ts +10 -10
  10. package/dist/helper.js +75 -75
  11. package/dist/history_server_capabilities.d.ts +35 -35
  12. package/dist/history_server_capabilities.js +43 -43
  13. package/dist/i_channel_data.d.ts +13 -13
  14. package/dist/i_channel_data.js +2 -2
  15. package/dist/i_register_server_manager.d.ts +16 -16
  16. package/dist/i_register_server_manager.js +2 -2
  17. package/dist/i_server_side_publish_engine.d.ts +36 -36
  18. package/dist/i_server_side_publish_engine.js +49 -49
  19. package/dist/i_socket_data.d.ts +11 -11
  20. package/dist/i_socket_data.js +2 -2
  21. package/dist/index.d.ts +16 -16
  22. package/dist/index.js +32 -32
  23. package/dist/monitored_item.d.ts +177 -177
  24. package/dist/monitored_item.js +1001 -1001
  25. package/dist/node_sampler.d.ts +3 -3
  26. package/dist/node_sampler.js +75 -75
  27. package/dist/opcua_server.d.ts +747 -747
  28. package/dist/opcua_server.js +2431 -2431
  29. package/dist/queue.d.ts +11 -11
  30. package/dist/queue.js +71 -71
  31. package/dist/register_server_manager.d.ts +96 -96
  32. package/dist/register_server_manager.js +584 -584
  33. package/dist/register_server_manager_hidden.d.ts +17 -17
  34. package/dist/register_server_manager_hidden.js +27 -27
  35. package/dist/register_server_manager_mdns_only.d.ts +22 -22
  36. package/dist/register_server_manager_mdns_only.js +55 -55
  37. package/dist/server_capabilities.d.ts +148 -148
  38. package/dist/server_capabilities.js +92 -92
  39. package/dist/server_end_point.d.ts +183 -183
  40. package/dist/server_end_point.js +817 -817
  41. package/dist/server_engine.d.ts +317 -317
  42. package/dist/server_engine.js +1716 -1716
  43. package/dist/server_publish_engine.d.ts +113 -113
  44. package/dist/server_publish_engine.js +541 -541
  45. package/dist/server_publish_engine_for_orphan_subscriptions.d.ts +16 -16
  46. package/dist/server_publish_engine_for_orphan_subscriptions.js +51 -51
  47. package/dist/server_session.d.ts +182 -182
  48. package/dist/server_session.js +739 -739
  49. package/dist/server_subscription.d.ts +421 -421
  50. package/dist/server_subscription.js +1346 -1346
  51. package/dist/sessions_compatible_for_transfer.d.ts +2 -2
  52. package/dist/sessions_compatible_for_transfer.js +39 -39
  53. package/dist/user_manager.d.ts +32 -32
  54. package/dist/user_manager.js +74 -74
  55. package/dist/user_manager_ua.d.ts +3 -3
  56. package/dist/user_manager_ua.js +39 -39
  57. package/dist/validate_filter.d.ts +5 -5
  58. package/dist/validate_filter.js +60 -60
  59. package/package.json +42 -41
@@ -1,818 +1,818 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.OPCUAServerEndPoint = void 0;
4
- /**
5
- * @module node-opcua-server
6
- */
7
- // tslint:disable:no-console
8
- const events_1 = require("events");
9
- const net = require("net");
10
- const chalk = require("chalk");
11
- const async = require("async");
12
- const node_opcua_assert_1 = require("node-opcua-assert");
13
- const node_opcua_crypto_1 = require("node-opcua-crypto");
14
- const node_opcua_debug_1 = require("node-opcua-debug");
15
- const node_opcua_hostname_1 = require("node-opcua-hostname");
16
- const node_opcua_secure_channel_1 = require("node-opcua-secure-channel");
17
- const node_opcua_service_endpoints_1 = require("node-opcua-service-endpoints");
18
- const node_opcua_service_endpoints_2 = require("node-opcua-service-endpoints");
19
- const node_opcua_service_endpoints_3 = require("node-opcua-service-endpoints");
20
- const debugLog = (0, node_opcua_debug_1.make_debugLog)(__filename);
21
- const errorLog = (0, node_opcua_debug_1.make_errorLog)(__filename);
22
- const warningLog = (0, node_opcua_debug_1.make_warningLog)(__filename);
23
- const doDebug = (0, node_opcua_debug_1.checkDebugFlag)(__filename);
24
- const default_transportProfileUri = "http://opcfoundation.org/UA-Profile/Transport/uatcp-uasc-uabinary";
25
- function extractSocketData(socket, reason) {
26
- const { bytesRead, bytesWritten, remoteAddress, remoteFamily, remotePort, localAddress, localPort } = socket;
27
- const data = {
28
- bytesRead,
29
- bytesWritten,
30
- localAddress,
31
- localPort,
32
- remoteAddress,
33
- remoteFamily,
34
- remotePort,
35
- timestamp: new Date(),
36
- reason
37
- };
38
- return data;
39
- }
40
- function extractChannelData(channel) {
41
- const { channelId, clientCertificate, clientNonce, clientSecurityHeader, securityHeader, securityMode, securityPolicy, timeout, transactionsCount } = channel;
42
- const channelData = {
43
- channelId,
44
- clientCertificate,
45
- clientNonce,
46
- clientSecurityHeader,
47
- securityHeader,
48
- securityMode,
49
- securityPolicy,
50
- timeout,
51
- transactionsCount
52
- };
53
- return channelData;
54
- }
55
- function dumpChannelInfo(channels) {
56
- function d(s) {
57
- return `[ status=${s.status} lastSeen=${s.clientLastContactTime.toFixed(0)}ms sessionName=${s.sessionName} timeout=${s.sessionTimeout} ]`;
58
- }
59
- function dumpChannel(channel) {
60
- var _a;
61
- console.log("------------------------------------------------------");
62
- console.log(" channelId = ", channel.channelId);
63
- console.log(" timeout = ", channel.timeout);
64
- console.log(" remoteAddress = ", channel.remoteAddress);
65
- console.log(" remotePort = ", channel.remotePort);
66
- console.log("");
67
- console.log(" bytesWritten = ", channel.bytesWritten);
68
- console.log(" bytesRead = ", channel.bytesRead);
69
- console.log(" sessions = ", Object.keys(channel.sessionTokens).length);
70
- console.log(Object.values(channel.sessionTokens).map(d).join("\n"));
71
- const socket = (_a = channel.transport) === null || _a === void 0 ? void 0 : _a._socket;
72
- if (!socket) {
73
- console.log(" SOCKET IS CLOSED");
74
- }
75
- }
76
- for (const channel of channels) {
77
- dumpChannel(channel);
78
- }
79
- console.log("------------------------------------------------------");
80
- }
81
- const emptyCertificate = Buffer.alloc(0);
82
- const emptyPrivateKeyPEM = "";
83
- let OPCUAServerEndPointCounter = 0;
84
- function getUniqueName(name, collection) {
85
- if (collection[name]) {
86
- let counter = 0;
87
- while (collection[name + "_" + counter.toString()]) {
88
- counter++;
89
- }
90
- name = name + "_" + counter.toString();
91
- collection[name] = 1;
92
- return name;
93
- }
94
- else {
95
- collection[name] = 1;
96
- return name;
97
- }
98
- }
99
- /**
100
- * OPCUAServerEndPoint a Server EndPoint.
101
- * A sever end point is listening to one port
102
- * note:
103
- * see OPCUA Release 1.03 part 4 page 108 7.1 ApplicationDescription
104
- */
105
- class OPCUAServerEndPoint extends events_1.EventEmitter {
106
- constructor(options) {
107
- super();
108
- this._started = false;
109
- this._counter = OPCUAServerEndPointCounter++;
110
- this._policy_deduplicator = {};
111
- (0, node_opcua_assert_1.assert)(!Object.prototype.hasOwnProperty.call(options, "certificate"), "expecting a certificateChain instead");
112
- (0, node_opcua_assert_1.assert)(Object.prototype.hasOwnProperty.call(options, "certificateChain"), "expecting a certificateChain");
113
- (0, node_opcua_assert_1.assert)(Object.prototype.hasOwnProperty.call(options, "privateKey"));
114
- this.certificateManager = options.certificateManager;
115
- options.port = options.port || 0;
116
- this.port = parseInt(options.port.toString(), 10);
117
- (0, node_opcua_assert_1.assert)(typeof this.port === "number");
118
- this._certificateChain = options.certificateChain;
119
- this._privateKey = options.privateKey;
120
- this._channels = {};
121
- this.defaultSecureTokenLifetime = options.defaultSecureTokenLifetime || 600000;
122
- this.maxConnections = options.maxConnections || 20;
123
- this.timeout = options.timeout || 30000;
124
- this._server = undefined;
125
- this._setup_server();
126
- this._endpoints = [];
127
- this.objectFactory = options.objectFactory;
128
- this.bytesWrittenInOldChannels = 0;
129
- this.bytesReadInOldChannels = 0;
130
- this.transactionsCountOldChannels = 0;
131
- this.securityTokenCountOldChannels = 0;
132
- this.serverInfo = options.serverInfo;
133
- (0, node_opcua_assert_1.assert)(this.serverInfo !== null && typeof this.serverInfo === "object");
134
- }
135
- dispose() {
136
- this._certificateChain = emptyCertificate;
137
- this._privateKey = emptyPrivateKeyPEM;
138
- (0, node_opcua_assert_1.assert)(Object.keys(this._channels).length === 0, "OPCUAServerEndPoint channels must have been deleted");
139
- this._channels = {};
140
- this.serverInfo = new node_opcua_service_endpoints_3.ApplicationDescription({});
141
- this._endpoints = [];
142
- (0, node_opcua_assert_1.assert)(this._endpoints.length === 0, "endpoints must have been deleted");
143
- this._endpoints = [];
144
- this._server = undefined;
145
- this._listen_callback = undefined;
146
- this.removeAllListeners();
147
- }
148
- toString() {
149
- const privateKey1 = (0, node_opcua_crypto_1.convertPEMtoDER)(this.getPrivateKey());
150
- const txt = " end point" +
151
- this._counter +
152
- " port = " +
153
- this.port +
154
- " l = " +
155
- this._endpoints.length +
156
- " " +
157
- (0, node_opcua_crypto_1.makeSHA1Thumbprint)(this.getCertificateChain()).toString("hex") +
158
- " " +
159
- (0, node_opcua_crypto_1.makeSHA1Thumbprint)(privateKey1).toString("hex");
160
- return txt;
161
- }
162
- getChannels() {
163
- return Object.values(this._channels);
164
- }
165
- /**
166
- * Returns the X509 DER form of the server certificate
167
- */
168
- getCertificate() {
169
- return (0, node_opcua_crypto_1.split_der)(this.getCertificateChain())[0];
170
- }
171
- /**
172
- * Returns the X509 DER form of the server certificate
173
- */
174
- getCertificateChain() {
175
- return this._certificateChain;
176
- }
177
- /**
178
- * the private key
179
- */
180
- getPrivateKey() {
181
- return this._privateKey;
182
- }
183
- /**
184
- * The number of active channel on this end point.
185
- */
186
- get currentChannelCount() {
187
- return Object.keys(this._channels).length;
188
- }
189
- /**
190
- * @method getEndpointDescription
191
- * @param securityMode
192
- * @param securityPolicy
193
- * @return endpoint_description {EndpointDescription|null}
194
- */
195
- getEndpointDescription(securityMode, securityPolicy, endpointUrl) {
196
- const endpoints = this.endpointDescriptions();
197
- const arr = endpoints.filter(matching_endpoint.bind(this, securityMode, securityPolicy, endpointUrl));
198
- if (endpointUrl && endpointUrl.length > 0 && !(arr.length === 0 || arr.length === 1)) {
199
- errorLog("Several matching endpoints have been found : ");
200
- for (const a of arr) {
201
- errorLog(" ", a.endpointUrl, node_opcua_secure_channel_1.MessageSecurityMode[securityMode], securityPolicy);
202
- }
203
- }
204
- return arr.length === 0 ? null : arr[0];
205
- }
206
- addEndpointDescription(securityMode, securityPolicy, options) {
207
- if (!options) {
208
- options = {
209
- hostname: (0, node_opcua_hostname_1.getFullyQualifiedDomainName)(),
210
- securityPolicies: [node_opcua_secure_channel_1.SecurityPolicy.Basic256Sha256]
211
- };
212
- }
213
- options.allowAnonymous = options.allowAnonymous === undefined ? true : options.allowAnonymous;
214
- // istanbul ignore next
215
- if (securityMode === node_opcua_secure_channel_1.MessageSecurityMode.None && securityPolicy !== node_opcua_secure_channel_1.SecurityPolicy.None) {
216
- throw new Error(" invalid security ");
217
- }
218
- // istanbul ignore next
219
- if (securityMode !== node_opcua_secure_channel_1.MessageSecurityMode.None && securityPolicy === node_opcua_secure_channel_1.SecurityPolicy.None) {
220
- throw new Error(" invalid security ");
221
- }
222
- //
223
- const port = this.port;
224
- // resource Path is a string added at the end of the url such as "/UA/Server"
225
- const resourcePath = (options.resourcePath || "").replace(/\\/g, "/");
226
- (0, node_opcua_assert_1.assert)(resourcePath.length === 0 || resourcePath.charAt(0) === "/", "resourcePath should start with /");
227
- const hostname = options.hostname || (0, node_opcua_hostname_1.getFullyQualifiedDomainName)();
228
- const endpointUrl = `opc.tcp://${hostname}:${port}${resourcePath}`;
229
- const endpoint_desc = this.getEndpointDescription(securityMode, securityPolicy, endpointUrl);
230
- // istanbul ignore next
231
- if (endpoint_desc) {
232
- throw new Error(" endpoint already exist");
233
- }
234
- // now build endpointUrl
235
- this._endpoints.push(_makeEndpointDescription({
236
- collection: this._policy_deduplicator,
237
- endpointUrl,
238
- hostname,
239
- port,
240
- server: this.serverInfo,
241
- serverCertificateChain: this.getCertificateChain(),
242
- securityMode,
243
- securityPolicy,
244
- allowAnonymous: options.allowAnonymous,
245
- allowUnsecurePassword: options.allowUnsecurePassword,
246
- resourcePath: options.resourcePath,
247
- restricted: !!options.restricted,
248
- securityPolicies: (options === null || options === void 0 ? void 0 : options.securityPolicies) || []
249
- }));
250
- }
251
- addRestrictedEndpointDescription(options) {
252
- options = Object.assign({}, options);
253
- options.restricted = true;
254
- return this.addEndpointDescription(node_opcua_secure_channel_1.MessageSecurityMode.None, node_opcua_secure_channel_1.SecurityPolicy.None, options);
255
- }
256
- addStandardEndpointDescriptions(options) {
257
- options = options || {};
258
- options.securityModes = options.securityModes || defaultSecurityModes;
259
- options.securityPolicies = options.securityPolicies || defaultSecurityPolicies;
260
- const defaultHostname = options.hostname || (0, node_opcua_hostname_1.getFullyQualifiedDomainName)();
261
- let hostnames = [defaultHostname];
262
- options.alternateHostname = options.alternateHostname || [];
263
- if (typeof options.alternateHostname === "string") {
264
- options.alternateHostname = [options.alternateHostname];
265
- }
266
- // remove duplicates if any (uniq)
267
- hostnames = [...new Set(hostnames.concat(options.alternateHostname))];
268
- for (const alternateHostname of hostnames) {
269
- const optionsE = options;
270
- optionsE.hostname = alternateHostname;
271
- if (options.securityModes.indexOf(node_opcua_secure_channel_1.MessageSecurityMode.None) >= 0) {
272
- this.addEndpointDescription(node_opcua_secure_channel_1.MessageSecurityMode.None, node_opcua_secure_channel_1.SecurityPolicy.None, optionsE);
273
- }
274
- else {
275
- if (!options.disableDiscovery) {
276
- this.addRestrictedEndpointDescription(optionsE);
277
- }
278
- }
279
- for (const securityMode of options.securityModes) {
280
- if (securityMode === node_opcua_secure_channel_1.MessageSecurityMode.None) {
281
- continue;
282
- }
283
- for (const securityPolicy of options.securityPolicies) {
284
- if (securityPolicy === node_opcua_secure_channel_1.SecurityPolicy.None) {
285
- continue;
286
- }
287
- this.addEndpointDescription(securityMode, securityPolicy, optionsE);
288
- }
289
- }
290
- }
291
- }
292
- /**
293
- * returns the list of end point descriptions.
294
- */
295
- endpointDescriptions() {
296
- return this._endpoints;
297
- }
298
- /**
299
- * @method listen
300
- * @async
301
- */
302
- listen(callback) {
303
- (0, node_opcua_assert_1.assert)(typeof callback === "function");
304
- (0, node_opcua_assert_1.assert)(!this._started, "OPCUAServerEndPoint is already listening");
305
- this._listen_callback = callback;
306
- this._server.on("error", (err) => {
307
- debugLog(chalk.red.bold(" error") + " port = " + this.port, err);
308
- this._started = false;
309
- this._end_listen(err);
310
- });
311
- this._server.on("listening", () => {
312
- debugLog("server is listening");
313
- });
314
- this._server.listen(this.port,
315
- /*"::",*/ (err) => {
316
- // 'listening' listener
317
- debugLog(chalk.green.bold("LISTENING TO PORT "), this.port, "err ", err);
318
- (0, node_opcua_assert_1.assert)(!err, " cannot listen to port ");
319
- this._started = true;
320
- this._end_listen();
321
- });
322
- }
323
- killClientSockets(callback) {
324
- for (const channel of this.getChannels()) {
325
- const hacked_channel = channel;
326
- if (hacked_channel.transport && hacked_channel.transport._socket) {
327
- // hacked_channel.transport._socket.close();
328
- hacked_channel.transport._socket.destroy();
329
- hacked_channel.transport._socket.emit("error", new Error("EPIPE"));
330
- }
331
- }
332
- callback();
333
- }
334
- suspendConnection(callback) {
335
- if (!this._started) {
336
- return callback(new Error("Connection already suspended !!"));
337
- }
338
- // Stops the server from accepting new connections and keeps existing connections.
339
- // (note from nodejs doc: This function is asynchronous, the server is finally closed
340
- // when all connections are ended and the server emits a 'close' event.
341
- // The optional callback will be called once the 'close' event occurs.
342
- // Unlike that event, it will be called with an Error as its only argument
343
- // if the server was not open when it was closed.
344
- this._server.close(() => {
345
- this._started = false;
346
- debugLog("Connection has been closed !" + this.port);
347
- });
348
- this._started = false;
349
- callback();
350
- }
351
- restoreConnection(callback) {
352
- this.listen(callback);
353
- }
354
- abruptlyInterruptChannels() {
355
- for (const channel of Object.values(this._channels)) {
356
- channel.abruptlyInterrupt();
357
- }
358
- }
359
- /**
360
- * @method shutdown
361
- * @async
362
- */
363
- shutdown(callback) {
364
- debugLog("OPCUAServerEndPoint#shutdown ");
365
- if (this._started) {
366
- // make sure we don't accept new connection any more ...
367
- this.suspendConnection(() => {
368
- // shutdown all opened channels ...
369
- const _channels = Object.values(this._channels);
370
- async.each(_channels, (channel, callback1) => {
371
- this.shutdown_channel(channel, callback1);
372
- }, (err) => {
373
- /* istanbul ignore next */
374
- if (!(Object.keys(this._channels).length === 0)) {
375
- errorLog(" Bad !");
376
- }
377
- (0, node_opcua_assert_1.assert)(Object.keys(this._channels).length === 0, "channel must have unregistered themselves");
378
- callback(err || undefined);
379
- });
380
- });
381
- }
382
- else {
383
- callback();
384
- }
385
- }
386
- /**
387
- * @method start
388
- * @async
389
- * @param callback
390
- */
391
- start(callback) {
392
- (0, node_opcua_assert_1.assert)(typeof callback === "function");
393
- this.listen(callback);
394
- }
395
- get bytesWritten() {
396
- const channels = Object.values(this._channels);
397
- return (this.bytesWrittenInOldChannels +
398
- channels.reduce((accumulated, channel) => {
399
- return accumulated + channel.bytesWritten;
400
- }, 0));
401
- }
402
- get bytesRead() {
403
- const channels = Object.values(this._channels);
404
- return (this.bytesReadInOldChannels +
405
- channels.reduce((accumulated, channel) => {
406
- return accumulated + channel.bytesRead;
407
- }, 0));
408
- }
409
- get transactionsCount() {
410
- const channels = Object.values(this._channels);
411
- return (this.transactionsCountOldChannels +
412
- channels.reduce((accumulated, channel) => {
413
- return accumulated + channel.transactionsCount;
414
- }, 0));
415
- }
416
- get securityTokenCount() {
417
- const channels = Object.values(this._channels);
418
- return (this.securityTokenCountOldChannels +
419
- channels.reduce((accumulated, channel) => {
420
- return accumulated + channel.securityTokenCount;
421
- }, 0));
422
- }
423
- get activeChannelCount() {
424
- return Object.keys(this._channels).length;
425
- }
426
- _dump_statistics() {
427
- this._server.getConnections((err, count) => {
428
- debugLog(chalk.cyan("CONCURRENT CONNECTION = "), count);
429
- });
430
- debugLog(chalk.cyan("MAX CONNECTIONS = "), this._server.maxConnections);
431
- }
432
- _setup_server() {
433
- (0, node_opcua_assert_1.assert)(!this._server);
434
- this._server = net.createServer({ pauseOnConnect: true }, this._on_client_connection.bind(this));
435
- // xx console.log(" Server with max connections ", self.maxConnections);
436
- this._server.maxConnections = this.maxConnections + 1; // plus one extra
437
- this._listen_callback = undefined;
438
- this._server
439
- .on("connection", (socket) => {
440
- // istanbul ignore next
441
- if (doDebug) {
442
- this._dump_statistics();
443
- debugLog("server connected with : " + socket.remoteAddress + ":" + socket.remotePort);
444
- }
445
- })
446
- .on("close", () => {
447
- debugLog("server closed : all connections have ended");
448
- })
449
- .on("error", (err) => {
450
- // this could be because the port is already in use
451
- debugLog(chalk.red.bold("server error: "), err.message);
452
- });
453
- }
454
- _on_client_connection(socket) {
455
- // a client is attempting a connection on the socket
456
- socket.setNoDelay(true);
457
- debugLog("OPCUAServerEndPoint#_on_client_connection", this._started);
458
- if (!this._started) {
459
- debugLog(chalk.bgWhite.cyan("OPCUAServerEndPoint#_on_client_connection " +
460
- "SERVER END POINT IS PROBABLY SHUTTING DOWN !!! - Connection is refused"));
461
- socket.end();
462
- return;
463
- }
464
- const deny_connection = () => {
465
- console.log(chalk.bgWhite.cyan("OPCUAServerEndPoint#_on_client_connection " +
466
- "The maximum number of connection has been reached - Connection is refused"));
467
- const reason = "maxConnections reached (" + this.maxConnections + ")";
468
- const socketData = extractSocketData(socket, reason);
469
- this.emit("connectionRefused", socketData);
470
- socket.end();
471
- socket.destroy();
472
- };
473
- const establish_connection = () => {
474
- const nbConnections = Object.keys(this._channels).length;
475
- if (nbConnections >= this.maxConnections) {
476
- warningLog(" nbConnections ", nbConnections, " self._server.maxConnections", this._server.maxConnections, this.maxConnections);
477
- deny_connection();
478
- return;
479
- }
480
- debugLog("OPCUAServerEndPoint._on_client_connection successful => New Channel");
481
- const channel = new node_opcua_secure_channel_1.ServerSecureChannelLayer({
482
- defaultSecureTokenLifetime: this.defaultSecureTokenLifetime,
483
- // objectFactory: this.objectFactory,
484
- parent: this,
485
- timeout: this.timeout
486
- });
487
- debugLog("channel Timeout = >", channel.timeout);
488
- socket.resume();
489
- this._preregisterChannel(channel);
490
- channel.init(socket, (err) => {
491
- this._un_pre_registerChannel(channel);
492
- debugLog(chalk.yellow.bold("Channel#init done"), err);
493
- if (err) {
494
- const reason = "openSecureChannel has Failed " + err.message;
495
- const socketData = extractSocketData(socket, reason);
496
- const channelData = extractChannelData(channel);
497
- this.emit("openSecureChannelFailure", socketData, channelData);
498
- socket.end();
499
- socket.destroy();
500
- }
501
- else {
502
- debugLog("server receiving a client connection");
503
- this._registerChannel(channel);
504
- }
505
- });
506
- channel.on("message", (message) => {
507
- // forward
508
- this.emit("message", message, channel, this);
509
- });
510
- };
511
- // Each SecureChannel exists until it is explicitly closed or until the last token has expired and the overlap
512
- // period has elapsed. A Server application should limit the number of SecureChannels.
513
- // To protect against misbehaving Clients and denial of service attacks, the Server shall close the oldest
514
- // SecureChannel that has no Session assigned before reaching the maximum number of supported SecureChannels.
515
- this._prevent_DDOS_Attack(establish_connection, deny_connection);
516
- }
517
- _preregisterChannel(channel) {
518
- // _preregisterChannel is used to keep track of channel for which
519
- // that are in early stage of the hand shaking process.
520
- // e.g HEL/ACK and OpenSecureChannel may not have been received yet
521
- // as they will need to be interrupted when OPCUAServerEndPoint is closed
522
- (0, node_opcua_assert_1.assert)(this._started, "OPCUAServerEndPoint must be started");
523
- (0, node_opcua_assert_1.assert)(!Object.prototype.hasOwnProperty.call(this._channels, channel.hashKey), " channel already preregistered!");
524
- const channelPriv = channel;
525
- this._channels[channel.hashKey] = channelPriv;
526
- channelPriv._unpreregisterChannelEvent = () => {
527
- debugLog("Channel received an abort event during the preregistration phase");
528
- this._un_pre_registerChannel(channel);
529
- channel.dispose();
530
- };
531
- channel.on("abort", channelPriv._unpreregisterChannelEvent);
532
- }
533
- _un_pre_registerChannel(channel) {
534
- if (!this._channels[channel.hashKey]) {
535
- debugLog("Already un preregistered ?", channel.hashKey);
536
- return;
537
- }
538
- delete this._channels[channel.hashKey];
539
- const channelPriv = channel;
540
- if (typeof channelPriv._unpreregisterChannelEvent === "function") {
541
- channel.removeListener("abort", channelPriv._unpreregisterChannelEvent);
542
- channelPriv._unpreregisterChannelEvent = undefined;
543
- }
544
- }
545
- /**
546
- * @method _registerChannel
547
- * @param channel
548
- * @private
549
- */
550
- _registerChannel(channel) {
551
- if (this._started) {
552
- debugLog(chalk.red("_registerChannel = "), "channel.hashKey = ", channel.hashKey);
553
- (0, node_opcua_assert_1.assert)(!this._channels[channel.hashKey]);
554
- this._channels[channel.hashKey] = channel;
555
- /**
556
- * @event newChannel
557
- * @param channel
558
- */
559
- this.emit("newChannel", channel);
560
- channel.on("abort", () => {
561
- this._unregisterChannel(channel);
562
- });
563
- }
564
- else {
565
- debugLog("OPCUAServerEndPoint#_registerChannel called when end point is shutdown !");
566
- debugLog(" -> channel will be forcefully terminated");
567
- channel.close();
568
- channel.dispose();
569
- }
570
- }
571
- /**
572
- * @method _unregisterChannel
573
- * @param channel
574
- * @private
575
- */
576
- _unregisterChannel(channel) {
577
- debugLog("_un-registerChannel channel.hashKey", channel.hashKey);
578
- if (!Object.prototype.hasOwnProperty.call(this._channels, channel.hashKey)) {
579
- return;
580
- }
581
- (0, node_opcua_assert_1.assert)(Object.prototype.hasOwnProperty.call(this._channels, channel.hashKey), "channel is not registered");
582
- /**
583
- * @event closeChannel
584
- * @param channel
585
- */
586
- this.emit("closeChannel", channel);
587
- // keep trace of statistics data from old channel for our own accumulated stats.
588
- this.bytesWrittenInOldChannels += channel.bytesWritten;
589
- this.bytesReadInOldChannels += channel.bytesRead;
590
- this.transactionsCountOldChannels += channel.transactionsCount;
591
- delete this._channels[channel.hashKey];
592
- // istanbul ignore next
593
- if (doDebug) {
594
- this._dump_statistics();
595
- debugLog("un-registering channel - Count = ", this.currentChannelCount);
596
- }
597
- /// channel.dispose();
598
- }
599
- _end_listen(err) {
600
- (0, node_opcua_assert_1.assert)(typeof this._listen_callback === "function");
601
- this._listen_callback(err);
602
- this._listen_callback = undefined;
603
- }
604
- /**
605
- * shutdown_channel
606
- * @param channel
607
- * @param inner_callback
608
- */
609
- shutdown_channel(channel, inner_callback) {
610
- (0, node_opcua_assert_1.assert)(typeof inner_callback === "function");
611
- channel.once("close", () => {
612
- // xx console.log(" ON CLOSED !!!!");
613
- });
614
- channel.close(() => {
615
- this._unregisterChannel(channel);
616
- setImmediate(inner_callback);
617
- });
618
- }
619
- /**
620
- * @private
621
- */
622
- _prevent_DDOS_Attack(establish_connection, deny_connection) {
623
- const nbConnections = this.activeChannelCount;
624
- if (nbConnections >= this.maxConnections) {
625
- // istanbul ignore next
626
- errorLog(chalk.bgRed.white("PREVENTING DDOS ATTACK => maxConnection =" + this.maxConnections));
627
- const unused_channels = this.getChannels().filter((channel1) => {
628
- return !channel1.isOpened && !channel1.hasSession;
629
- });
630
- if (unused_channels.length === 0) {
631
- // all channels are in used , we cannot get any
632
- errorLog("All channels are in used ! let cancel some");
633
- // istanbul ignore next
634
- if (doDebug) {
635
- console.log(" - all channels are used !!!!");
636
- dumpChannelInfo(this.getChannels());
637
- }
638
- setTimeout(deny_connection, 10);
639
- return;
640
- }
641
- // istanbul ignore next
642
- if (doDebug) {
643
- console.log(" - Unused channels that can be clobbered", unused_channels.map((channel1) => channel1.hashKey).join(" "));
644
- }
645
- const channel = unused_channels[0];
646
- errorLog("Closing channel ", channel.hashKey);
647
- channel.close(() => {
648
- // istanbul ignore next
649
- if (doDebug) {
650
- console.log(" _ Unused channel has been closed ", channel.hashKey);
651
- }
652
- this._unregisterChannel(channel);
653
- establish_connection();
654
- });
655
- }
656
- else {
657
- setImmediate(establish_connection);
658
- }
659
- }
660
- }
661
- exports.OPCUAServerEndPoint = OPCUAServerEndPoint;
662
- function estimateSecurityLevel(securityMode, securityPolicy) {
663
- if (securityMode === node_opcua_secure_channel_1.MessageSecurityMode.None) {
664
- return 1;
665
- }
666
- let offset = 100;
667
- if (securityMode === node_opcua_secure_channel_1.MessageSecurityMode.SignAndEncrypt) {
668
- offset = 200;
669
- }
670
- switch (securityPolicy) {
671
- case node_opcua_secure_channel_1.SecurityPolicy.Basic128:
672
- case node_opcua_secure_channel_1.SecurityPolicy.Basic128Rsa15:
673
- case node_opcua_secure_channel_1.SecurityPolicy.Basic192:
674
- return 2; // deprecated => low
675
- case node_opcua_secure_channel_1.SecurityPolicy.Basic192Rsa15:
676
- return 3; // deprecated => low
677
- case node_opcua_secure_channel_1.SecurityPolicy.Basic256:
678
- return 4; // deprecated => low
679
- case node_opcua_secure_channel_1.SecurityPolicy.Basic256Rsa15:
680
- return 4 + offset;
681
- case node_opcua_secure_channel_1.SecurityPolicy.Aes128_Sha256_RsaOaep:
682
- return 5 + offset;
683
- case node_opcua_secure_channel_1.SecurityPolicy.Basic256Sha256:
684
- return 6 + offset;
685
- case node_opcua_secure_channel_1.SecurityPolicy.Aes256_Sha256_RsaPss:
686
- return 7 + offset;
687
- default:
688
- case node_opcua_secure_channel_1.SecurityPolicy.None:
689
- return 1;
690
- }
691
- }
692
- /**
693
- * @private
694
- */
695
- function _makeEndpointDescription(options) {
696
- (0, node_opcua_assert_1.assert)(isFinite(options.port), "expecting a valid port number");
697
- (0, node_opcua_assert_1.assert)(Object.prototype.hasOwnProperty.call(options, "serverCertificateChain"));
698
- (0, node_opcua_assert_1.assert)(!Object.prototype.hasOwnProperty.call(options, "serverCertificate"));
699
- (0, node_opcua_assert_1.assert)(!!options.securityMode); // s.MessageSecurityMode
700
- (0, node_opcua_assert_1.assert)(!!options.securityPolicy);
701
- (0, node_opcua_assert_1.assert)(options.server !== null && typeof options.server === "object");
702
- (0, node_opcua_assert_1.assert)(!!options.hostname && typeof options.hostname === "string");
703
- (0, node_opcua_assert_1.assert)(typeof options.restricted === "boolean");
704
- const u = (n) => getUniqueName(n, options.collection);
705
- options.securityLevel =
706
- options.securityLevel === undefined
707
- ? estimateSecurityLevel(options.securityMode, options.securityPolicy)
708
- : options.securityLevel;
709
- (0, node_opcua_assert_1.assert)(isFinite(options.securityLevel), "expecting a valid securityLevel");
710
- const securityPolicyUri = (0, node_opcua_secure_channel_1.toURI)(options.securityPolicy);
711
- const userIdentityTokens = [];
712
- if (options.securityPolicy === node_opcua_secure_channel_1.SecurityPolicy.None) {
713
- if (options.allowUnsecurePassword) {
714
- userIdentityTokens.push({
715
- policyId: u("username_unsecure"),
716
- tokenType: node_opcua_service_endpoints_1.UserTokenType.UserName,
717
- issuedTokenType: null,
718
- issuerEndpointUrl: null,
719
- securityPolicyUri: null
720
- });
721
- }
722
- const a = (tokenType, securityPolicy, name) => {
723
- if (options.securityPolicies.indexOf(securityPolicy) >= 0) {
724
- userIdentityTokens.push({
725
- policyId: u(name),
726
- tokenType,
727
- issuedTokenType: null,
728
- issuerEndpointUrl: null,
729
- securityPolicyUri: securityPolicy
730
- });
731
- }
732
- };
733
- const onlyCertificateLessConnection = options.onlyCertificateLessConnection === undefined ? false : options.onlyCertificateLessConnection;
734
- if (!onlyCertificateLessConnection) {
735
- a(node_opcua_service_endpoints_1.UserTokenType.UserName, node_opcua_secure_channel_1.SecurityPolicy.Basic256, "username_basic256");
736
- a(node_opcua_service_endpoints_1.UserTokenType.UserName, node_opcua_secure_channel_1.SecurityPolicy.Basic128Rsa15, "username_basic128Rsa15");
737
- a(node_opcua_service_endpoints_1.UserTokenType.UserName, node_opcua_secure_channel_1.SecurityPolicy.Basic256Sha256, "username_basic256Sha256");
738
- a(node_opcua_service_endpoints_1.UserTokenType.UserName, node_opcua_secure_channel_1.SecurityPolicy.Aes128_Sha256_RsaOaep, "username_aes128Sha256RsaOaep");
739
- // X509
740
- a(node_opcua_service_endpoints_1.UserTokenType.Certificate, node_opcua_secure_channel_1.SecurityPolicy.Basic256, "certificate_basic256");
741
- a(node_opcua_service_endpoints_1.UserTokenType.Certificate, node_opcua_secure_channel_1.SecurityPolicy.Basic128Rsa15, "certificate_basic128Rsa15");
742
- a(node_opcua_service_endpoints_1.UserTokenType.Certificate, node_opcua_secure_channel_1.SecurityPolicy.Basic256Sha256, "certificate_basic256Sha256");
743
- a(node_opcua_service_endpoints_1.UserTokenType.Certificate, node_opcua_secure_channel_1.SecurityPolicy.Aes128_Sha256_RsaOaep, "certificate_aes128Sha256RsaOaep");
744
- }
745
- }
746
- else {
747
- // note:
748
- // when channel session security is not "None",
749
- // userIdentityTokens can be left to null.
750
- // in this case this mean that secure policy will be the same as connection security policy
751
- userIdentityTokens.push({
752
- policyId: u("usernamePassword"),
753
- tokenType: node_opcua_service_endpoints_1.UserTokenType.UserName,
754
- issuedTokenType: null,
755
- issuerEndpointUrl: null,
756
- securityPolicyUri: null
757
- });
758
- userIdentityTokens.push({
759
- policyId: u("certificateX509"),
760
- tokenType: node_opcua_service_endpoints_1.UserTokenType.Certificate,
761
- issuedTokenType: null,
762
- issuerEndpointUrl: null,
763
- securityPolicyUri: null
764
- });
765
- }
766
- if (options.allowAnonymous) {
767
- userIdentityTokens.push({
768
- policyId: u("anonymous"),
769
- tokenType: node_opcua_service_endpoints_1.UserTokenType.Anonymous,
770
- issuedTokenType: null,
771
- issuerEndpointUrl: null,
772
- securityPolicyUri: null
773
- });
774
- }
775
- // return the endpoint object
776
- const endpoint = new node_opcua_service_endpoints_2.EndpointDescription({
777
- endpointUrl: options.endpointUrl,
778
- server: undefined,
779
- serverCertificate: options.serverCertificateChain,
780
- securityMode: options.securityMode,
781
- securityPolicyUri,
782
- userIdentityTokens,
783
- securityLevel: options.securityLevel,
784
- transportProfileUri: default_transportProfileUri
785
- });
786
- endpoint.__defineGetter__("endpointUrl", () => {
787
- return (0, node_opcua_hostname_1.resolveFullyQualifiedDomainName)(options.endpointUrl);
788
- });
789
- endpoint.server = options.server;
790
- endpoint.restricted = options.restricted;
791
- return endpoint;
792
- }
793
- /**
794
- * return true if the end point matches security mode and policy
795
- * @param endpoint
796
- * @param securityMode
797
- * @param securityPolicy
798
- * @internal
799
- *
800
- */
801
- function matching_endpoint(securityMode, securityPolicy, endpointUrl, endpoint) {
802
- (0, node_opcua_assert_1.assert)(endpoint instanceof node_opcua_service_endpoints_2.EndpointDescription);
803
- const endpoint_securityPolicy = (0, node_opcua_secure_channel_1.fromURI)(endpoint.securityPolicyUri);
804
- if (endpointUrl && endpoint.endpointUrl !== endpointUrl) {
805
- return false;
806
- }
807
- return endpoint.securityMode === securityMode && endpoint_securityPolicy === securityPolicy;
808
- }
809
- const defaultSecurityModes = [node_opcua_secure_channel_1.MessageSecurityMode.None, node_opcua_secure_channel_1.MessageSecurityMode.Sign, node_opcua_secure_channel_1.MessageSecurityMode.SignAndEncrypt];
810
- const defaultSecurityPolicies = [
811
- node_opcua_secure_channel_1.SecurityPolicy.Basic128Rsa15,
812
- node_opcua_secure_channel_1.SecurityPolicy.Basic256,
813
- // xx UNUSED!! SecurityPolicy.Basic256Rsa15,
814
- node_opcua_secure_channel_1.SecurityPolicy.Basic256Sha256,
815
- node_opcua_secure_channel_1.SecurityPolicy.Aes128_Sha256_RsaOaep
816
- // NO USED YET SecurityPolicy.Aes256_Sha256_RsaPss
817
- ];
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OPCUAServerEndPoint = void 0;
4
+ /**
5
+ * @module node-opcua-server
6
+ */
7
+ // tslint:disable:no-console
8
+ const events_1 = require("events");
9
+ const net = require("net");
10
+ const chalk = require("chalk");
11
+ const async = require("async");
12
+ const node_opcua_assert_1 = require("node-opcua-assert");
13
+ const node_opcua_crypto_1 = require("node-opcua-crypto");
14
+ const node_opcua_debug_1 = require("node-opcua-debug");
15
+ const node_opcua_hostname_1 = require("node-opcua-hostname");
16
+ const node_opcua_secure_channel_1 = require("node-opcua-secure-channel");
17
+ const node_opcua_service_endpoints_1 = require("node-opcua-service-endpoints");
18
+ const node_opcua_service_endpoints_2 = require("node-opcua-service-endpoints");
19
+ const node_opcua_service_endpoints_3 = require("node-opcua-service-endpoints");
20
+ const debugLog = (0, node_opcua_debug_1.make_debugLog)(__filename);
21
+ const errorLog = (0, node_opcua_debug_1.make_errorLog)(__filename);
22
+ const warningLog = (0, node_opcua_debug_1.make_warningLog)(__filename);
23
+ const doDebug = (0, node_opcua_debug_1.checkDebugFlag)(__filename);
24
+ const default_transportProfileUri = "http://opcfoundation.org/UA-Profile/Transport/uatcp-uasc-uabinary";
25
+ function extractSocketData(socket, reason) {
26
+ const { bytesRead, bytesWritten, remoteAddress, remoteFamily, remotePort, localAddress, localPort } = socket;
27
+ const data = {
28
+ bytesRead,
29
+ bytesWritten,
30
+ localAddress,
31
+ localPort,
32
+ remoteAddress,
33
+ remoteFamily,
34
+ remotePort,
35
+ timestamp: new Date(),
36
+ reason
37
+ };
38
+ return data;
39
+ }
40
+ function extractChannelData(channel) {
41
+ const { channelId, clientCertificate, clientNonce, clientSecurityHeader, securityHeader, securityMode, securityPolicy, timeout, transactionsCount } = channel;
42
+ const channelData = {
43
+ channelId,
44
+ clientCertificate,
45
+ clientNonce,
46
+ clientSecurityHeader,
47
+ securityHeader,
48
+ securityMode,
49
+ securityPolicy,
50
+ timeout,
51
+ transactionsCount
52
+ };
53
+ return channelData;
54
+ }
55
+ function dumpChannelInfo(channels) {
56
+ function d(s) {
57
+ return `[ status=${s.status} lastSeen=${s.clientLastContactTime.toFixed(0)}ms sessionName=${s.sessionName} timeout=${s.sessionTimeout} ]`;
58
+ }
59
+ function dumpChannel(channel) {
60
+ var _a;
61
+ console.log("------------------------------------------------------");
62
+ console.log(" channelId = ", channel.channelId);
63
+ console.log(" timeout = ", channel.timeout);
64
+ console.log(" remoteAddress = ", channel.remoteAddress);
65
+ console.log(" remotePort = ", channel.remotePort);
66
+ console.log("");
67
+ console.log(" bytesWritten = ", channel.bytesWritten);
68
+ console.log(" bytesRead = ", channel.bytesRead);
69
+ console.log(" sessions = ", Object.keys(channel.sessionTokens).length);
70
+ console.log(Object.values(channel.sessionTokens).map(d).join("\n"));
71
+ const socket = (_a = channel.transport) === null || _a === void 0 ? void 0 : _a._socket;
72
+ if (!socket) {
73
+ console.log(" SOCKET IS CLOSED");
74
+ }
75
+ }
76
+ for (const channel of channels) {
77
+ dumpChannel(channel);
78
+ }
79
+ console.log("------------------------------------------------------");
80
+ }
81
+ const emptyCertificate = Buffer.alloc(0);
82
+ const emptyPrivateKeyPEM = "";
83
+ let OPCUAServerEndPointCounter = 0;
84
+ function getUniqueName(name, collection) {
85
+ if (collection[name]) {
86
+ let counter = 0;
87
+ while (collection[name + "_" + counter.toString()]) {
88
+ counter++;
89
+ }
90
+ name = name + "_" + counter.toString();
91
+ collection[name] = 1;
92
+ return name;
93
+ }
94
+ else {
95
+ collection[name] = 1;
96
+ return name;
97
+ }
98
+ }
99
+ /**
100
+ * OPCUAServerEndPoint a Server EndPoint.
101
+ * A sever end point is listening to one port
102
+ * note:
103
+ * see OPCUA Release 1.03 part 4 page 108 7.1 ApplicationDescription
104
+ */
105
+ class OPCUAServerEndPoint extends events_1.EventEmitter {
106
+ constructor(options) {
107
+ super();
108
+ this._started = false;
109
+ this._counter = OPCUAServerEndPointCounter++;
110
+ this._policy_deduplicator = {};
111
+ (0, node_opcua_assert_1.assert)(!Object.prototype.hasOwnProperty.call(options, "certificate"), "expecting a certificateChain instead");
112
+ (0, node_opcua_assert_1.assert)(Object.prototype.hasOwnProperty.call(options, "certificateChain"), "expecting a certificateChain");
113
+ (0, node_opcua_assert_1.assert)(Object.prototype.hasOwnProperty.call(options, "privateKey"));
114
+ this.certificateManager = options.certificateManager;
115
+ options.port = options.port || 0;
116
+ this.port = parseInt(options.port.toString(), 10);
117
+ (0, node_opcua_assert_1.assert)(typeof this.port === "number");
118
+ this._certificateChain = options.certificateChain;
119
+ this._privateKey = options.privateKey;
120
+ this._channels = {};
121
+ this.defaultSecureTokenLifetime = options.defaultSecureTokenLifetime || 600000;
122
+ this.maxConnections = options.maxConnections || 20;
123
+ this.timeout = options.timeout || 30000;
124
+ this._server = undefined;
125
+ this._setup_server();
126
+ this._endpoints = [];
127
+ this.objectFactory = options.objectFactory;
128
+ this.bytesWrittenInOldChannels = 0;
129
+ this.bytesReadInOldChannels = 0;
130
+ this.transactionsCountOldChannels = 0;
131
+ this.securityTokenCountOldChannels = 0;
132
+ this.serverInfo = options.serverInfo;
133
+ (0, node_opcua_assert_1.assert)(this.serverInfo !== null && typeof this.serverInfo === "object");
134
+ }
135
+ dispose() {
136
+ this._certificateChain = emptyCertificate;
137
+ this._privateKey = emptyPrivateKeyPEM;
138
+ (0, node_opcua_assert_1.assert)(Object.keys(this._channels).length === 0, "OPCUAServerEndPoint channels must have been deleted");
139
+ this._channels = {};
140
+ this.serverInfo = new node_opcua_service_endpoints_3.ApplicationDescription({});
141
+ this._endpoints = [];
142
+ (0, node_opcua_assert_1.assert)(this._endpoints.length === 0, "endpoints must have been deleted");
143
+ this._endpoints = [];
144
+ this._server = undefined;
145
+ this._listen_callback = undefined;
146
+ this.removeAllListeners();
147
+ }
148
+ toString() {
149
+ const privateKey1 = (0, node_opcua_crypto_1.convertPEMtoDER)(this.getPrivateKey());
150
+ const txt = " end point" +
151
+ this._counter +
152
+ " port = " +
153
+ this.port +
154
+ " l = " +
155
+ this._endpoints.length +
156
+ " " +
157
+ (0, node_opcua_crypto_1.makeSHA1Thumbprint)(this.getCertificateChain()).toString("hex") +
158
+ " " +
159
+ (0, node_opcua_crypto_1.makeSHA1Thumbprint)(privateKey1).toString("hex");
160
+ return txt;
161
+ }
162
+ getChannels() {
163
+ return Object.values(this._channels);
164
+ }
165
+ /**
166
+ * Returns the X509 DER form of the server certificate
167
+ */
168
+ getCertificate() {
169
+ return (0, node_opcua_crypto_1.split_der)(this.getCertificateChain())[0];
170
+ }
171
+ /**
172
+ * Returns the X509 DER form of the server certificate
173
+ */
174
+ getCertificateChain() {
175
+ return this._certificateChain;
176
+ }
177
+ /**
178
+ * the private key
179
+ */
180
+ getPrivateKey() {
181
+ return this._privateKey;
182
+ }
183
+ /**
184
+ * The number of active channel on this end point.
185
+ */
186
+ get currentChannelCount() {
187
+ return Object.keys(this._channels).length;
188
+ }
189
+ /**
190
+ * @method getEndpointDescription
191
+ * @param securityMode
192
+ * @param securityPolicy
193
+ * @return endpoint_description {EndpointDescription|null}
194
+ */
195
+ getEndpointDescription(securityMode, securityPolicy, endpointUrl) {
196
+ const endpoints = this.endpointDescriptions();
197
+ const arr = endpoints.filter(matching_endpoint.bind(this, securityMode, securityPolicy, endpointUrl));
198
+ if (endpointUrl && endpointUrl.length > 0 && !(arr.length === 0 || arr.length === 1)) {
199
+ errorLog("Several matching endpoints have been found : ");
200
+ for (const a of arr) {
201
+ errorLog(" ", a.endpointUrl, node_opcua_secure_channel_1.MessageSecurityMode[securityMode], securityPolicy);
202
+ }
203
+ }
204
+ return arr.length === 0 ? null : arr[0];
205
+ }
206
+ addEndpointDescription(securityMode, securityPolicy, options) {
207
+ if (!options) {
208
+ options = {
209
+ hostname: (0, node_opcua_hostname_1.getFullyQualifiedDomainName)(),
210
+ securityPolicies: [node_opcua_secure_channel_1.SecurityPolicy.Basic256Sha256]
211
+ };
212
+ }
213
+ options.allowAnonymous = options.allowAnonymous === undefined ? true : options.allowAnonymous;
214
+ // istanbul ignore next
215
+ if (securityMode === node_opcua_secure_channel_1.MessageSecurityMode.None && securityPolicy !== node_opcua_secure_channel_1.SecurityPolicy.None) {
216
+ throw new Error(" invalid security ");
217
+ }
218
+ // istanbul ignore next
219
+ if (securityMode !== node_opcua_secure_channel_1.MessageSecurityMode.None && securityPolicy === node_opcua_secure_channel_1.SecurityPolicy.None) {
220
+ throw new Error(" invalid security ");
221
+ }
222
+ //
223
+ const port = this.port;
224
+ // resource Path is a string added at the end of the url such as "/UA/Server"
225
+ const resourcePath = (options.resourcePath || "").replace(/\\/g, "/");
226
+ (0, node_opcua_assert_1.assert)(resourcePath.length === 0 || resourcePath.charAt(0) === "/", "resourcePath should start with /");
227
+ const hostname = options.hostname || (0, node_opcua_hostname_1.getFullyQualifiedDomainName)();
228
+ const endpointUrl = `opc.tcp://${hostname}:${port}${resourcePath}`;
229
+ const endpoint_desc = this.getEndpointDescription(securityMode, securityPolicy, endpointUrl);
230
+ // istanbul ignore next
231
+ if (endpoint_desc) {
232
+ throw new Error(" endpoint already exist");
233
+ }
234
+ // now build endpointUrl
235
+ this._endpoints.push(_makeEndpointDescription({
236
+ collection: this._policy_deduplicator,
237
+ endpointUrl,
238
+ hostname,
239
+ port,
240
+ server: this.serverInfo,
241
+ serverCertificateChain: this.getCertificateChain(),
242
+ securityMode,
243
+ securityPolicy,
244
+ allowAnonymous: options.allowAnonymous,
245
+ allowUnsecurePassword: options.allowUnsecurePassword,
246
+ resourcePath: options.resourcePath,
247
+ restricted: !!options.restricted,
248
+ securityPolicies: (options === null || options === void 0 ? void 0 : options.securityPolicies) || []
249
+ }));
250
+ }
251
+ addRestrictedEndpointDescription(options) {
252
+ options = Object.assign({}, options);
253
+ options.restricted = true;
254
+ return this.addEndpointDescription(node_opcua_secure_channel_1.MessageSecurityMode.None, node_opcua_secure_channel_1.SecurityPolicy.None, options);
255
+ }
256
+ addStandardEndpointDescriptions(options) {
257
+ options = options || {};
258
+ options.securityModes = options.securityModes || defaultSecurityModes;
259
+ options.securityPolicies = options.securityPolicies || defaultSecurityPolicies;
260
+ const defaultHostname = options.hostname || (0, node_opcua_hostname_1.getFullyQualifiedDomainName)();
261
+ let hostnames = [defaultHostname];
262
+ options.alternateHostname = options.alternateHostname || [];
263
+ if (typeof options.alternateHostname === "string") {
264
+ options.alternateHostname = [options.alternateHostname];
265
+ }
266
+ // remove duplicates if any (uniq)
267
+ hostnames = [...new Set(hostnames.concat(options.alternateHostname))];
268
+ for (const alternateHostname of hostnames) {
269
+ const optionsE = options;
270
+ optionsE.hostname = alternateHostname;
271
+ if (options.securityModes.indexOf(node_opcua_secure_channel_1.MessageSecurityMode.None) >= 0) {
272
+ this.addEndpointDescription(node_opcua_secure_channel_1.MessageSecurityMode.None, node_opcua_secure_channel_1.SecurityPolicy.None, optionsE);
273
+ }
274
+ else {
275
+ if (!options.disableDiscovery) {
276
+ this.addRestrictedEndpointDescription(optionsE);
277
+ }
278
+ }
279
+ for (const securityMode of options.securityModes) {
280
+ if (securityMode === node_opcua_secure_channel_1.MessageSecurityMode.None) {
281
+ continue;
282
+ }
283
+ for (const securityPolicy of options.securityPolicies) {
284
+ if (securityPolicy === node_opcua_secure_channel_1.SecurityPolicy.None) {
285
+ continue;
286
+ }
287
+ this.addEndpointDescription(securityMode, securityPolicy, optionsE);
288
+ }
289
+ }
290
+ }
291
+ }
292
+ /**
293
+ * returns the list of end point descriptions.
294
+ */
295
+ endpointDescriptions() {
296
+ return this._endpoints;
297
+ }
298
+ /**
299
+ * @method listen
300
+ * @async
301
+ */
302
+ listen(callback) {
303
+ (0, node_opcua_assert_1.assert)(typeof callback === "function");
304
+ (0, node_opcua_assert_1.assert)(!this._started, "OPCUAServerEndPoint is already listening");
305
+ this._listen_callback = callback;
306
+ this._server.on("error", (err) => {
307
+ debugLog(chalk.red.bold(" error") + " port = " + this.port, err);
308
+ this._started = false;
309
+ this._end_listen(err);
310
+ });
311
+ this._server.on("listening", () => {
312
+ debugLog("server is listening");
313
+ });
314
+ this._server.listen(this.port,
315
+ /*"::",*/ (err) => {
316
+ // 'listening' listener
317
+ debugLog(chalk.green.bold("LISTENING TO PORT "), this.port, "err ", err);
318
+ (0, node_opcua_assert_1.assert)(!err, " cannot listen to port ");
319
+ this._started = true;
320
+ this._end_listen();
321
+ });
322
+ }
323
+ killClientSockets(callback) {
324
+ for (const channel of this.getChannels()) {
325
+ const hacked_channel = channel;
326
+ if (hacked_channel.transport && hacked_channel.transport._socket) {
327
+ // hacked_channel.transport._socket.close();
328
+ hacked_channel.transport._socket.destroy();
329
+ hacked_channel.transport._socket.emit("error", new Error("EPIPE"));
330
+ }
331
+ }
332
+ callback();
333
+ }
334
+ suspendConnection(callback) {
335
+ if (!this._started) {
336
+ return callback(new Error("Connection already suspended !!"));
337
+ }
338
+ // Stops the server from accepting new connections and keeps existing connections.
339
+ // (note from nodejs doc: This function is asynchronous, the server is finally closed
340
+ // when all connections are ended and the server emits a 'close' event.
341
+ // The optional callback will be called once the 'close' event occurs.
342
+ // Unlike that event, it will be called with an Error as its only argument
343
+ // if the server was not open when it was closed.
344
+ this._server.close(() => {
345
+ this._started = false;
346
+ debugLog("Connection has been closed !" + this.port);
347
+ });
348
+ this._started = false;
349
+ callback();
350
+ }
351
+ restoreConnection(callback) {
352
+ this.listen(callback);
353
+ }
354
+ abruptlyInterruptChannels() {
355
+ for (const channel of Object.values(this._channels)) {
356
+ channel.abruptlyInterrupt();
357
+ }
358
+ }
359
+ /**
360
+ * @method shutdown
361
+ * @async
362
+ */
363
+ shutdown(callback) {
364
+ debugLog("OPCUAServerEndPoint#shutdown ");
365
+ if (this._started) {
366
+ // make sure we don't accept new connection any more ...
367
+ this.suspendConnection(() => {
368
+ // shutdown all opened channels ...
369
+ const _channels = Object.values(this._channels);
370
+ async.each(_channels, (channel, callback1) => {
371
+ this.shutdown_channel(channel, callback1);
372
+ }, (err) => {
373
+ /* istanbul ignore next */
374
+ if (!(Object.keys(this._channels).length === 0)) {
375
+ errorLog(" Bad !");
376
+ }
377
+ (0, node_opcua_assert_1.assert)(Object.keys(this._channels).length === 0, "channel must have unregistered themselves");
378
+ callback(err || undefined);
379
+ });
380
+ });
381
+ }
382
+ else {
383
+ callback();
384
+ }
385
+ }
386
+ /**
387
+ * @method start
388
+ * @async
389
+ * @param callback
390
+ */
391
+ start(callback) {
392
+ (0, node_opcua_assert_1.assert)(typeof callback === "function");
393
+ this.listen(callback);
394
+ }
395
+ get bytesWritten() {
396
+ const channels = Object.values(this._channels);
397
+ return (this.bytesWrittenInOldChannels +
398
+ channels.reduce((accumulated, channel) => {
399
+ return accumulated + channel.bytesWritten;
400
+ }, 0));
401
+ }
402
+ get bytesRead() {
403
+ const channels = Object.values(this._channels);
404
+ return (this.bytesReadInOldChannels +
405
+ channels.reduce((accumulated, channel) => {
406
+ return accumulated + channel.bytesRead;
407
+ }, 0));
408
+ }
409
+ get transactionsCount() {
410
+ const channels = Object.values(this._channels);
411
+ return (this.transactionsCountOldChannels +
412
+ channels.reduce((accumulated, channel) => {
413
+ return accumulated + channel.transactionsCount;
414
+ }, 0));
415
+ }
416
+ get securityTokenCount() {
417
+ const channels = Object.values(this._channels);
418
+ return (this.securityTokenCountOldChannels +
419
+ channels.reduce((accumulated, channel) => {
420
+ return accumulated + channel.securityTokenCount;
421
+ }, 0));
422
+ }
423
+ get activeChannelCount() {
424
+ return Object.keys(this._channels).length;
425
+ }
426
+ _dump_statistics() {
427
+ this._server.getConnections((err, count) => {
428
+ debugLog(chalk.cyan("CONCURRENT CONNECTION = "), count);
429
+ });
430
+ debugLog(chalk.cyan("MAX CONNECTIONS = "), this._server.maxConnections);
431
+ }
432
+ _setup_server() {
433
+ (0, node_opcua_assert_1.assert)(!this._server);
434
+ this._server = net.createServer({ pauseOnConnect: true }, this._on_client_connection.bind(this));
435
+ // xx console.log(" Server with max connections ", self.maxConnections);
436
+ this._server.maxConnections = this.maxConnections + 1; // plus one extra
437
+ this._listen_callback = undefined;
438
+ this._server
439
+ .on("connection", (socket) => {
440
+ // istanbul ignore next
441
+ if (doDebug) {
442
+ this._dump_statistics();
443
+ debugLog("server connected with : " + socket.remoteAddress + ":" + socket.remotePort);
444
+ }
445
+ })
446
+ .on("close", () => {
447
+ debugLog("server closed : all connections have ended");
448
+ })
449
+ .on("error", (err) => {
450
+ // this could be because the port is already in use
451
+ debugLog(chalk.red.bold("server error: "), err.message);
452
+ });
453
+ }
454
+ _on_client_connection(socket) {
455
+ // a client is attempting a connection on the socket
456
+ socket.setNoDelay(true);
457
+ debugLog("OPCUAServerEndPoint#_on_client_connection", this._started);
458
+ if (!this._started) {
459
+ debugLog(chalk.bgWhite.cyan("OPCUAServerEndPoint#_on_client_connection " +
460
+ "SERVER END POINT IS PROBABLY SHUTTING DOWN !!! - Connection is refused"));
461
+ socket.end();
462
+ return;
463
+ }
464
+ const deny_connection = () => {
465
+ console.log(chalk.bgWhite.cyan("OPCUAServerEndPoint#_on_client_connection " +
466
+ "The maximum number of connection has been reached - Connection is refused"));
467
+ const reason = "maxConnections reached (" + this.maxConnections + ")";
468
+ const socketData = extractSocketData(socket, reason);
469
+ this.emit("connectionRefused", socketData);
470
+ socket.end();
471
+ socket.destroy();
472
+ };
473
+ const establish_connection = () => {
474
+ const nbConnections = Object.keys(this._channels).length;
475
+ if (nbConnections >= this.maxConnections) {
476
+ warningLog(" nbConnections ", nbConnections, " self._server.maxConnections", this._server.maxConnections, this.maxConnections);
477
+ deny_connection();
478
+ return;
479
+ }
480
+ debugLog("OPCUAServerEndPoint._on_client_connection successful => New Channel");
481
+ const channel = new node_opcua_secure_channel_1.ServerSecureChannelLayer({
482
+ defaultSecureTokenLifetime: this.defaultSecureTokenLifetime,
483
+ // objectFactory: this.objectFactory,
484
+ parent: this,
485
+ timeout: this.timeout
486
+ });
487
+ debugLog("channel Timeout = >", channel.timeout);
488
+ socket.resume();
489
+ this._preregisterChannel(channel);
490
+ channel.init(socket, (err) => {
491
+ this._un_pre_registerChannel(channel);
492
+ debugLog(chalk.yellow.bold("Channel#init done"), err);
493
+ if (err) {
494
+ const reason = "openSecureChannel has Failed " + err.message;
495
+ const socketData = extractSocketData(socket, reason);
496
+ const channelData = extractChannelData(channel);
497
+ this.emit("openSecureChannelFailure", socketData, channelData);
498
+ socket.end();
499
+ socket.destroy();
500
+ }
501
+ else {
502
+ debugLog("server receiving a client connection");
503
+ this._registerChannel(channel);
504
+ }
505
+ });
506
+ channel.on("message", (message) => {
507
+ // forward
508
+ this.emit("message", message, channel, this);
509
+ });
510
+ };
511
+ // Each SecureChannel exists until it is explicitly closed or until the last token has expired and the overlap
512
+ // period has elapsed. A Server application should limit the number of SecureChannels.
513
+ // To protect against misbehaving Clients and denial of service attacks, the Server shall close the oldest
514
+ // SecureChannel that has no Session assigned before reaching the maximum number of supported SecureChannels.
515
+ this._prevent_DDOS_Attack(establish_connection, deny_connection);
516
+ }
517
+ _preregisterChannel(channel) {
518
+ // _preregisterChannel is used to keep track of channel for which
519
+ // that are in early stage of the hand shaking process.
520
+ // e.g HEL/ACK and OpenSecureChannel may not have been received yet
521
+ // as they will need to be interrupted when OPCUAServerEndPoint is closed
522
+ (0, node_opcua_assert_1.assert)(this._started, "OPCUAServerEndPoint must be started");
523
+ (0, node_opcua_assert_1.assert)(!Object.prototype.hasOwnProperty.call(this._channels, channel.hashKey), " channel already preregistered!");
524
+ const channelPriv = channel;
525
+ this._channels[channel.hashKey] = channelPriv;
526
+ channelPriv._unpreregisterChannelEvent = () => {
527
+ debugLog("Channel received an abort event during the preregistration phase");
528
+ this._un_pre_registerChannel(channel);
529
+ channel.dispose();
530
+ };
531
+ channel.on("abort", channelPriv._unpreregisterChannelEvent);
532
+ }
533
+ _un_pre_registerChannel(channel) {
534
+ if (!this._channels[channel.hashKey]) {
535
+ debugLog("Already un preregistered ?", channel.hashKey);
536
+ return;
537
+ }
538
+ delete this._channels[channel.hashKey];
539
+ const channelPriv = channel;
540
+ if (typeof channelPriv._unpreregisterChannelEvent === "function") {
541
+ channel.removeListener("abort", channelPriv._unpreregisterChannelEvent);
542
+ channelPriv._unpreregisterChannelEvent = undefined;
543
+ }
544
+ }
545
+ /**
546
+ * @method _registerChannel
547
+ * @param channel
548
+ * @private
549
+ */
550
+ _registerChannel(channel) {
551
+ if (this._started) {
552
+ debugLog(chalk.red("_registerChannel = "), "channel.hashKey = ", channel.hashKey);
553
+ (0, node_opcua_assert_1.assert)(!this._channels[channel.hashKey]);
554
+ this._channels[channel.hashKey] = channel;
555
+ /**
556
+ * @event newChannel
557
+ * @param channel
558
+ */
559
+ this.emit("newChannel", channel);
560
+ channel.on("abort", () => {
561
+ this._unregisterChannel(channel);
562
+ });
563
+ }
564
+ else {
565
+ debugLog("OPCUAServerEndPoint#_registerChannel called when end point is shutdown !");
566
+ debugLog(" -> channel will be forcefully terminated");
567
+ channel.close();
568
+ channel.dispose();
569
+ }
570
+ }
571
+ /**
572
+ * @method _unregisterChannel
573
+ * @param channel
574
+ * @private
575
+ */
576
+ _unregisterChannel(channel) {
577
+ debugLog("_un-registerChannel channel.hashKey", channel.hashKey);
578
+ if (!Object.prototype.hasOwnProperty.call(this._channels, channel.hashKey)) {
579
+ return;
580
+ }
581
+ (0, node_opcua_assert_1.assert)(Object.prototype.hasOwnProperty.call(this._channels, channel.hashKey), "channel is not registered");
582
+ /**
583
+ * @event closeChannel
584
+ * @param channel
585
+ */
586
+ this.emit("closeChannel", channel);
587
+ // keep trace of statistics data from old channel for our own accumulated stats.
588
+ this.bytesWrittenInOldChannels += channel.bytesWritten;
589
+ this.bytesReadInOldChannels += channel.bytesRead;
590
+ this.transactionsCountOldChannels += channel.transactionsCount;
591
+ delete this._channels[channel.hashKey];
592
+ // istanbul ignore next
593
+ if (doDebug) {
594
+ this._dump_statistics();
595
+ debugLog("un-registering channel - Count = ", this.currentChannelCount);
596
+ }
597
+ /// channel.dispose();
598
+ }
599
+ _end_listen(err) {
600
+ (0, node_opcua_assert_1.assert)(typeof this._listen_callback === "function");
601
+ this._listen_callback(err);
602
+ this._listen_callback = undefined;
603
+ }
604
+ /**
605
+ * shutdown_channel
606
+ * @param channel
607
+ * @param inner_callback
608
+ */
609
+ shutdown_channel(channel, inner_callback) {
610
+ (0, node_opcua_assert_1.assert)(typeof inner_callback === "function");
611
+ channel.once("close", () => {
612
+ // xx console.log(" ON CLOSED !!!!");
613
+ });
614
+ channel.close(() => {
615
+ this._unregisterChannel(channel);
616
+ setImmediate(inner_callback);
617
+ });
618
+ }
619
+ /**
620
+ * @private
621
+ */
622
+ _prevent_DDOS_Attack(establish_connection, deny_connection) {
623
+ const nbConnections = this.activeChannelCount;
624
+ if (nbConnections >= this.maxConnections) {
625
+ // istanbul ignore next
626
+ errorLog(chalk.bgRed.white("PREVENTING DDOS ATTACK => maxConnection =" + this.maxConnections));
627
+ const unused_channels = this.getChannels().filter((channel1) => {
628
+ return !channel1.isOpened && !channel1.hasSession;
629
+ });
630
+ if (unused_channels.length === 0) {
631
+ // all channels are in used , we cannot get any
632
+ errorLog("All channels are in used ! let cancel some");
633
+ // istanbul ignore next
634
+ if (doDebug) {
635
+ console.log(" - all channels are used !!!!");
636
+ dumpChannelInfo(this.getChannels());
637
+ }
638
+ setTimeout(deny_connection, 10);
639
+ return;
640
+ }
641
+ // istanbul ignore next
642
+ if (doDebug) {
643
+ console.log(" - Unused channels that can be clobbered", unused_channels.map((channel1) => channel1.hashKey).join(" "));
644
+ }
645
+ const channel = unused_channels[0];
646
+ errorLog("Closing channel ", channel.hashKey);
647
+ channel.close(() => {
648
+ // istanbul ignore next
649
+ if (doDebug) {
650
+ console.log(" _ Unused channel has been closed ", channel.hashKey);
651
+ }
652
+ this._unregisterChannel(channel);
653
+ establish_connection();
654
+ });
655
+ }
656
+ else {
657
+ setImmediate(establish_connection);
658
+ }
659
+ }
660
+ }
661
+ exports.OPCUAServerEndPoint = OPCUAServerEndPoint;
662
+ function estimateSecurityLevel(securityMode, securityPolicy) {
663
+ if (securityMode === node_opcua_secure_channel_1.MessageSecurityMode.None) {
664
+ return 1;
665
+ }
666
+ let offset = 100;
667
+ if (securityMode === node_opcua_secure_channel_1.MessageSecurityMode.SignAndEncrypt) {
668
+ offset = 200;
669
+ }
670
+ switch (securityPolicy) {
671
+ case node_opcua_secure_channel_1.SecurityPolicy.Basic128:
672
+ case node_opcua_secure_channel_1.SecurityPolicy.Basic128Rsa15:
673
+ case node_opcua_secure_channel_1.SecurityPolicy.Basic192:
674
+ return 2; // deprecated => low
675
+ case node_opcua_secure_channel_1.SecurityPolicy.Basic192Rsa15:
676
+ return 3; // deprecated => low
677
+ case node_opcua_secure_channel_1.SecurityPolicy.Basic256:
678
+ return 4; // deprecated => low
679
+ case node_opcua_secure_channel_1.SecurityPolicy.Basic256Rsa15:
680
+ return 4 + offset;
681
+ case node_opcua_secure_channel_1.SecurityPolicy.Aes128_Sha256_RsaOaep:
682
+ return 5 + offset;
683
+ case node_opcua_secure_channel_1.SecurityPolicy.Basic256Sha256:
684
+ return 6 + offset;
685
+ case node_opcua_secure_channel_1.SecurityPolicy.Aes256_Sha256_RsaPss:
686
+ return 7 + offset;
687
+ default:
688
+ case node_opcua_secure_channel_1.SecurityPolicy.None:
689
+ return 1;
690
+ }
691
+ }
692
+ /**
693
+ * @private
694
+ */
695
+ function _makeEndpointDescription(options) {
696
+ (0, node_opcua_assert_1.assert)(isFinite(options.port), "expecting a valid port number");
697
+ (0, node_opcua_assert_1.assert)(Object.prototype.hasOwnProperty.call(options, "serverCertificateChain"));
698
+ (0, node_opcua_assert_1.assert)(!Object.prototype.hasOwnProperty.call(options, "serverCertificate"));
699
+ (0, node_opcua_assert_1.assert)(!!options.securityMode); // s.MessageSecurityMode
700
+ (0, node_opcua_assert_1.assert)(!!options.securityPolicy);
701
+ (0, node_opcua_assert_1.assert)(options.server !== null && typeof options.server === "object");
702
+ (0, node_opcua_assert_1.assert)(!!options.hostname && typeof options.hostname === "string");
703
+ (0, node_opcua_assert_1.assert)(typeof options.restricted === "boolean");
704
+ const u = (n) => getUniqueName(n, options.collection);
705
+ options.securityLevel =
706
+ options.securityLevel === undefined
707
+ ? estimateSecurityLevel(options.securityMode, options.securityPolicy)
708
+ : options.securityLevel;
709
+ (0, node_opcua_assert_1.assert)(isFinite(options.securityLevel), "expecting a valid securityLevel");
710
+ const securityPolicyUri = (0, node_opcua_secure_channel_1.toURI)(options.securityPolicy);
711
+ const userIdentityTokens = [];
712
+ if (options.securityPolicy === node_opcua_secure_channel_1.SecurityPolicy.None) {
713
+ if (options.allowUnsecurePassword) {
714
+ userIdentityTokens.push({
715
+ policyId: u("username_unsecure"),
716
+ tokenType: node_opcua_service_endpoints_1.UserTokenType.UserName,
717
+ issuedTokenType: null,
718
+ issuerEndpointUrl: null,
719
+ securityPolicyUri: null
720
+ });
721
+ }
722
+ const a = (tokenType, securityPolicy, name) => {
723
+ if (options.securityPolicies.indexOf(securityPolicy) >= 0) {
724
+ userIdentityTokens.push({
725
+ policyId: u(name),
726
+ tokenType,
727
+ issuedTokenType: null,
728
+ issuerEndpointUrl: null,
729
+ securityPolicyUri: securityPolicy
730
+ });
731
+ }
732
+ };
733
+ const onlyCertificateLessConnection = options.onlyCertificateLessConnection === undefined ? false : options.onlyCertificateLessConnection;
734
+ if (!onlyCertificateLessConnection) {
735
+ a(node_opcua_service_endpoints_1.UserTokenType.UserName, node_opcua_secure_channel_1.SecurityPolicy.Basic256, "username_basic256");
736
+ a(node_opcua_service_endpoints_1.UserTokenType.UserName, node_opcua_secure_channel_1.SecurityPolicy.Basic128Rsa15, "username_basic128Rsa15");
737
+ a(node_opcua_service_endpoints_1.UserTokenType.UserName, node_opcua_secure_channel_1.SecurityPolicy.Basic256Sha256, "username_basic256Sha256");
738
+ a(node_opcua_service_endpoints_1.UserTokenType.UserName, node_opcua_secure_channel_1.SecurityPolicy.Aes128_Sha256_RsaOaep, "username_aes128Sha256RsaOaep");
739
+ // X509
740
+ a(node_opcua_service_endpoints_1.UserTokenType.Certificate, node_opcua_secure_channel_1.SecurityPolicy.Basic256, "certificate_basic256");
741
+ a(node_opcua_service_endpoints_1.UserTokenType.Certificate, node_opcua_secure_channel_1.SecurityPolicy.Basic128Rsa15, "certificate_basic128Rsa15");
742
+ a(node_opcua_service_endpoints_1.UserTokenType.Certificate, node_opcua_secure_channel_1.SecurityPolicy.Basic256Sha256, "certificate_basic256Sha256");
743
+ a(node_opcua_service_endpoints_1.UserTokenType.Certificate, node_opcua_secure_channel_1.SecurityPolicy.Aes128_Sha256_RsaOaep, "certificate_aes128Sha256RsaOaep");
744
+ }
745
+ }
746
+ else {
747
+ // note:
748
+ // when channel session security is not "None",
749
+ // userIdentityTokens can be left to null.
750
+ // in this case this mean that secure policy will be the same as connection security policy
751
+ userIdentityTokens.push({
752
+ policyId: u("usernamePassword"),
753
+ tokenType: node_opcua_service_endpoints_1.UserTokenType.UserName,
754
+ issuedTokenType: null,
755
+ issuerEndpointUrl: null,
756
+ securityPolicyUri: null
757
+ });
758
+ userIdentityTokens.push({
759
+ policyId: u("certificateX509"),
760
+ tokenType: node_opcua_service_endpoints_1.UserTokenType.Certificate,
761
+ issuedTokenType: null,
762
+ issuerEndpointUrl: null,
763
+ securityPolicyUri: null
764
+ });
765
+ }
766
+ if (options.allowAnonymous) {
767
+ userIdentityTokens.push({
768
+ policyId: u("anonymous"),
769
+ tokenType: node_opcua_service_endpoints_1.UserTokenType.Anonymous,
770
+ issuedTokenType: null,
771
+ issuerEndpointUrl: null,
772
+ securityPolicyUri: null
773
+ });
774
+ }
775
+ // return the endpoint object
776
+ const endpoint = new node_opcua_service_endpoints_2.EndpointDescription({
777
+ endpointUrl: options.endpointUrl,
778
+ server: undefined,
779
+ serverCertificate: options.serverCertificateChain,
780
+ securityMode: options.securityMode,
781
+ securityPolicyUri,
782
+ userIdentityTokens,
783
+ securityLevel: options.securityLevel,
784
+ transportProfileUri: default_transportProfileUri
785
+ });
786
+ endpoint.__defineGetter__("endpointUrl", () => {
787
+ return (0, node_opcua_hostname_1.resolveFullyQualifiedDomainName)(options.endpointUrl);
788
+ });
789
+ endpoint.server = options.server;
790
+ endpoint.restricted = options.restricted;
791
+ return endpoint;
792
+ }
793
+ /**
794
+ * return true if the end point matches security mode and policy
795
+ * @param endpoint
796
+ * @param securityMode
797
+ * @param securityPolicy
798
+ * @internal
799
+ *
800
+ */
801
+ function matching_endpoint(securityMode, securityPolicy, endpointUrl, endpoint) {
802
+ (0, node_opcua_assert_1.assert)(endpoint instanceof node_opcua_service_endpoints_2.EndpointDescription);
803
+ const endpoint_securityPolicy = (0, node_opcua_secure_channel_1.fromURI)(endpoint.securityPolicyUri);
804
+ if (endpointUrl && endpoint.endpointUrl !== endpointUrl) {
805
+ return false;
806
+ }
807
+ return endpoint.securityMode === securityMode && endpoint_securityPolicy === securityPolicy;
808
+ }
809
+ const defaultSecurityModes = [node_opcua_secure_channel_1.MessageSecurityMode.None, node_opcua_secure_channel_1.MessageSecurityMode.Sign, node_opcua_secure_channel_1.MessageSecurityMode.SignAndEncrypt];
810
+ const defaultSecurityPolicies = [
811
+ node_opcua_secure_channel_1.SecurityPolicy.Basic128Rsa15,
812
+ node_opcua_secure_channel_1.SecurityPolicy.Basic256,
813
+ // xx UNUSED!! SecurityPolicy.Basic256Rsa15,
814
+ node_opcua_secure_channel_1.SecurityPolicy.Basic256Sha256,
815
+ node_opcua_secure_channel_1.SecurityPolicy.Aes128_Sha256_RsaOaep
816
+ // NO USED YET SecurityPolicy.Aes256_Sha256_RsaPss
817
+ ];
818
818
  //# sourceMappingURL=server_end_point.js.map