node-opcua-server 2.82.0 → 2.84.0

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.
@@ -27,6 +27,7 @@ import {
27
27
  import { UserTokenType } from "node-opcua-service-endpoints";
28
28
  import { EndpointDescription } from "node-opcua-service-endpoints";
29
29
  import { ApplicationDescription } from "node-opcua-service-endpoints";
30
+ import { UserTokenPolicyOptions } from "node-opcua-types";
30
31
  import { IChannelData } from "./i_channel_data";
31
32
  import { ISocketData } from "./i_socket_data";
32
33
 
@@ -155,26 +156,27 @@ export interface OPCUAServerEndPointOptions {
155
156
  }
156
157
 
157
158
  export interface EndpointDescriptionParams {
158
- allowAnonymous?: boolean;
159
159
  restricted?: boolean;
160
160
  allowUnsecurePassword?: boolean;
161
161
  resourcePath?: string;
162
162
  alternateHostname?: string[];
163
163
  hostname: string;
164
164
  securityPolicies: SecurityPolicy[];
165
+ userTokenTypes: UserTokenType[];
165
166
  }
166
167
 
167
168
  export interface AddStandardEndpointDescriptionsParam {
168
- securityModes?: MessageSecurityMode[];
169
- securityPolicies?: SecurityPolicy[];
170
- disableDiscovery?: boolean;
171
-
172
169
  allowAnonymous?: boolean;
170
+ disableDiscovery?: boolean;
171
+ securityModes?: MessageSecurityMode[];
172
+
173
173
  restricted?: boolean;
174
- hostname?: string;
175
- alternateHostname?: string[];
176
174
  allowUnsecurePassword?: boolean;
177
175
  resourcePath?: string;
176
+ alternateHostname?: string[];
177
+ hostname?: string;
178
+ securityPolicies?: SecurityPolicy[];
179
+ userTokenTypes?: UserTokenType[];
178
180
  }
179
181
 
180
182
  function getUniqueName(name: string, collection: { [key: string]: number }) {
@@ -367,17 +369,8 @@ export class OPCUAServerEndPoint extends EventEmitter implements ServerSecureCha
367
369
  public addEndpointDescription(
368
370
  securityMode: MessageSecurityMode,
369
371
  securityPolicy: SecurityPolicy,
370
- options?: EndpointDescriptionParams
372
+ options: EndpointDescriptionParams
371
373
  ): void {
372
- if (!options) {
373
- options = {
374
- hostname: getFullyQualifiedDomainName(),
375
- securityPolicies: [SecurityPolicy.Basic256Sha256]
376
- };
377
- }
378
-
379
- options.allowAnonymous = options.allowAnonymous === undefined ? true : options.allowAnonymous;
380
-
381
374
  // istanbul ignore next
382
375
  if (securityMode === MessageSecurityMode.None && securityPolicy !== SecurityPolicy.None) {
383
376
  throw new Error(" invalid security ");
@@ -405,6 +398,8 @@ export class OPCUAServerEndPoint extends EventEmitter implements ServerSecureCha
405
398
  throw new Error(" endpoint already exist");
406
399
  }
407
400
 
401
+ const userTokenTypes = options.userTokenTypes;
402
+
408
403
  // now build endpointUrl
409
404
  this._endpoints.push(
410
405
  _makeEndpointDescription({
@@ -419,12 +414,13 @@ export class OPCUAServerEndPoint extends EventEmitter implements ServerSecureCha
419
414
  securityMode,
420
415
  securityPolicy,
421
416
 
422
- allowAnonymous: options.allowAnonymous,
423
417
  allowUnsecurePassword: options.allowUnsecurePassword,
424
418
  resourcePath: options.resourcePath,
425
419
 
426
420
  restricted: !!options.restricted,
427
- securityPolicies: options?.securityPolicies || []
421
+ securityPolicies: options.securityPolicies || [],
422
+
423
+ userTokenTypes
428
424
  })
429
425
  );
430
426
  }
@@ -440,6 +436,14 @@ export class OPCUAServerEndPoint extends EventEmitter implements ServerSecureCha
440
436
 
441
437
  options.securityModes = options.securityModes || defaultSecurityModes;
442
438
  options.securityPolicies = options.securityPolicies || defaultSecurityPolicies;
439
+ options.userTokenTypes = options.userTokenTypes || defaultUserTokenTypes;
440
+
441
+ options.allowAnonymous = options.allowAnonymous === undefined ? true : options.allowAnonymous;
442
+ // make sure we do not have anonymous
443
+ if (!options.allowAnonymous) {
444
+ options.userTokenTypes = options.userTokenTypes.filter((r) => r !== UserTokenType.Anonymous);
445
+ }
446
+
443
447
 
444
448
  const defaultHostname = options.hostname || getFullyQualifiedDomainName();
445
449
 
@@ -450,11 +454,17 @@ export class OPCUAServerEndPoint extends EventEmitter implements ServerSecureCha
450
454
  options.alternateHostname = [options.alternateHostname];
451
455
  }
452
456
  // remove duplicates if any (uniq)
453
- hostnames = [...new Set(hostnames.concat(options.alternateHostname as string[]))];
457
+ hostnames = [...new Set(hostnames.concat(options.alternateHostname))];
454
458
 
455
459
  for (const alternateHostname of hostnames) {
456
- const optionsE = options as EndpointDescriptionParams;
457
- optionsE.hostname = alternateHostname;
460
+ const optionsE: EndpointDescriptionParams = {
461
+ hostname: alternateHostname,
462
+ securityPolicies: options.securityPolicies,
463
+ userTokenTypes: options.userTokenTypes,
464
+ allowUnsecurePassword: options.allowUnsecurePassword,
465
+ alternateHostname: options.alternateHostname,
466
+ resourcePath: options.resourcePath
467
+ };
458
468
 
459
469
  if (options.securityModes.indexOf(MessageSecurityMode.None) >= 0) {
460
470
  this.addEndpointDescription(MessageSecurityMode.None, SecurityPolicy.None, optionsE);
@@ -966,7 +976,6 @@ interface MakeEndpointDescriptionOptions {
966
976
  };
967
977
  */
968
978
  resourcePath?: string;
969
- allowAnonymous?: boolean; // default true
970
979
 
971
980
  // allow un-encrypted password in userNameIdentity
972
981
  allowUnsecurePassword?: boolean; // default false
@@ -981,6 +990,15 @@ interface MakeEndpointDescriptionOptions {
981
990
  collection: { [key: string]: number };
982
991
 
983
992
  securityPolicies: SecurityPolicy[];
993
+
994
+ userTokenTypes: UserTokenType[];
995
+ /**
996
+ *
997
+ * default value: false;
998
+ *
999
+ * note: setting noUserIdentityTokens=true is useful for pure local discovery servers
1000
+ */
1001
+ noUserIdentityTokens?: boolean;
984
1002
  }
985
1003
 
986
1004
  interface EndpointDescriptionEx extends EndpointDescription {
@@ -1040,72 +1058,85 @@ function _makeEndpointDescription(options: MakeEndpointDescriptionOptions): Endp
1040
1058
 
1041
1059
  const securityPolicyUri = toURI(options.securityPolicy);
1042
1060
 
1043
- const userIdentityTokens = [];
1044
-
1045
- if (options.securityPolicy === SecurityPolicy.None) {
1046
- if (options.allowUnsecurePassword) {
1047
- userIdentityTokens.push({
1048
- policyId: u("username_unsecure"),
1049
- tokenType: UserTokenType.UserName,
1061
+ const userIdentityTokens: UserTokenPolicyOptions[] = [];
1050
1062
 
1051
- issuedTokenType: null,
1052
- issuerEndpointUrl: null,
1053
- securityPolicyUri: null
1054
- });
1063
+ const registerIdentity2 = (tokenType: UserTokenType, securityPolicy: SecurityPolicy, name: string) => {
1064
+ return registerIdentity({
1065
+ policyId: u(name),
1066
+ tokenType,
1067
+ issuedTokenType: null,
1068
+ issuerEndpointUrl: null,
1069
+ securityPolicyUri: securityPolicy
1070
+ });
1071
+ };
1072
+ const registerIdentity = (r: UserTokenPolicyOptions) => {
1073
+ const tokenType = r.tokenType === undefined ? UserTokenType.Invalid : r.tokenType;
1074
+ const securityPolicy = (r.securityPolicyUri || "") as SecurityPolicy;
1075
+ if (!securityPolicy && options.userTokenTypes.indexOf(tokenType) >= 0) {
1076
+ userIdentityTokens.push(r);
1077
+ return;
1055
1078
  }
1079
+ if (options.securityPolicies.indexOf(securityPolicy) >= 0 && options.userTokenTypes.indexOf(tokenType) >= 0) {
1080
+ userIdentityTokens.push(r);
1081
+ }
1082
+ };
1083
+
1084
+ if (!options.noUserIdentityTokens) {
1085
+ if (options.securityPolicy === SecurityPolicy.None) {
1086
+ if (options.allowUnsecurePassword) {
1087
+ registerIdentity({
1088
+ policyId: u("username_unsecure"),
1089
+ tokenType: UserTokenType.UserName,
1056
1090
 
1057
- const a = (tokenType: UserTokenType, securityPolicy: SecurityPolicy, name: string) => {
1058
- if (options.securityPolicies.indexOf(securityPolicy) >= 0) {
1059
- userIdentityTokens.push({
1060
- policyId: u(name),
1061
- tokenType,
1062
1091
  issuedTokenType: null,
1063
1092
  issuerEndpointUrl: null,
1064
- securityPolicyUri: securityPolicy
1093
+ securityPolicyUri: null
1065
1094
  });
1066
1095
  }
1067
- };
1068
- const onlyCertificateLessConnection =
1069
- options.onlyCertificateLessConnection === undefined ? false : options.onlyCertificateLessConnection;
1070
-
1071
- if (!onlyCertificateLessConnection) {
1072
- a(UserTokenType.UserName, SecurityPolicy.Basic256, "username_basic256");
1073
- a(UserTokenType.UserName, SecurityPolicy.Basic128Rsa15, "username_basic128Rsa15");
1074
- a(UserTokenType.UserName, SecurityPolicy.Basic256Sha256, "username_basic256Sha256");
1075
- a(UserTokenType.UserName, SecurityPolicy.Aes128_Sha256_RsaOaep, "username_aes128Sha256RsaOaep");
1076
-
1077
- // X509
1078
- a(UserTokenType.Certificate, SecurityPolicy.Basic256, "certificate_basic256");
1079
- a(UserTokenType.Certificate, SecurityPolicy.Basic128Rsa15, "certificate_basic128Rsa15");
1080
- a(UserTokenType.Certificate, SecurityPolicy.Basic256Sha256, "certificate_basic256Sha256");
1081
- a(UserTokenType.Certificate, SecurityPolicy.Aes128_Sha256_RsaOaep, "certificate_aes128Sha256RsaOaep");
1082
- }
1083
- } else {
1084
- // note:
1085
- // when channel session security is not "None",
1086
- // userIdentityTokens can be left to null.
1087
- // in this case this mean that secure policy will be the same as connection security policy
1088
- userIdentityTokens.push({
1089
- policyId: u("usernamePassword"),
1090
- tokenType: UserTokenType.UserName,
1091
1096
 
1092
- issuedTokenType: null,
1093
- issuerEndpointUrl: null,
1094
- securityPolicyUri: null
1095
- });
1097
+ const onlyCertificateLessConnection =
1098
+ options.onlyCertificateLessConnection === undefined ? false : options.onlyCertificateLessConnection;
1099
+
1100
+ if (!onlyCertificateLessConnection) {
1101
+ registerIdentity2(UserTokenType.UserName, SecurityPolicy.Basic256, "username_basic256");
1102
+ registerIdentity2(UserTokenType.UserName, SecurityPolicy.Basic128Rsa15, "username_basic128Rsa15");
1103
+ registerIdentity2(UserTokenType.UserName, SecurityPolicy.Basic256Sha256, "username_basic256Sha256");
1104
+ registerIdentity2(UserTokenType.UserName, SecurityPolicy.Aes128_Sha256_RsaOaep, "username_aes128Sha256RsaOaep");
1105
+
1106
+ // X509
1107
+ registerIdentity2(UserTokenType.Certificate, SecurityPolicy.Basic256, "certificate_basic256");
1108
+ registerIdentity2(UserTokenType.Certificate, SecurityPolicy.Basic128Rsa15, "certificate_basic128Rsa15");
1109
+ registerIdentity2(UserTokenType.Certificate, SecurityPolicy.Basic256Sha256, "certificate_basic256Sha256");
1110
+ registerIdentity2(
1111
+ UserTokenType.Certificate,
1112
+ SecurityPolicy.Aes128_Sha256_RsaOaep,
1113
+ "certificate_aes128Sha256RsaOaep"
1114
+ );
1115
+ }
1116
+ } else {
1117
+ // note:
1118
+ // when channel session security is not "None",
1119
+ // userIdentityTokens can be left to null.
1120
+ // in this case this mean that secure policy will be the same as connection security policy
1121
+ registerIdentity({
1122
+ policyId: u("usernamePassword"),
1123
+ tokenType: UserTokenType.UserName,
1124
+ issuedTokenType: null,
1125
+ issuerEndpointUrl: null,
1126
+ securityPolicyUri: null
1127
+ });
1096
1128
 
1097
- userIdentityTokens.push({
1098
- policyId: u("certificateX509"),
1099
- tokenType: UserTokenType.Certificate,
1129
+ registerIdentity({
1130
+ policyId: u("certificateX509"),
1131
+ tokenType: UserTokenType.Certificate,
1100
1132
 
1101
- issuedTokenType: null,
1102
- issuerEndpointUrl: null,
1103
- securityPolicyUri: null
1104
- });
1105
- }
1133
+ issuedTokenType: null,
1134
+ issuerEndpointUrl: null,
1135
+ securityPolicyUri: null
1136
+ });
1137
+ }
1106
1138
 
1107
- if (options.allowAnonymous) {
1108
- userIdentityTokens.push({
1139
+ registerIdentity({
1109
1140
  policyId: u("anonymous"),
1110
1141
  tokenType: UserTokenType.Anonymous,
1111
1142
 
@@ -1114,7 +1145,6 @@ function _makeEndpointDescription(options: MakeEndpointDescriptionOptions): Endp
1114
1145
  securityPolicyUri: null
1115
1146
  });
1116
1147
  }
1117
-
1118
1148
  // return the endpoint object
1119
1149
  const endpoint = new EndpointDescription({
1120
1150
  endpointUrl: options.endpointUrl,
@@ -1172,3 +1202,10 @@ const defaultSecurityPolicies = [
1172
1202
  SecurityPolicy.Aes128_Sha256_RsaOaep
1173
1203
  // NO USED YET SecurityPolicy.Aes256_Sha256_RsaPss
1174
1204
  ];
1205
+
1206
+ const defaultUserTokenTypes = [
1207
+ UserTokenType.Anonymous,
1208
+ UserTokenType.UserName,
1209
+ UserTokenType.Certificate
1210
+ // NOT USED YET : UserTokenType.IssuedToken
1211
+ ];