zeroc-ice 3.8.1 → 3.8.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 (129) hide show
  1. checksums.yaml +4 -4
  2. data/dist/IceRuby/Operation.cpp +22 -6
  3. data/dist/ice/cpp/include/Ice/Config.h +2 -2
  4. data/dist/ice/cpp/include/Ice/LocalExceptions.h +21 -0
  5. data/dist/ice/cpp/include/Ice/OutputStream.h +7 -5
  6. data/dist/ice/cpp/include/generated/Ice/BuiltinSequences.h +2 -2
  7. data/dist/ice/cpp/include/generated/Ice/Context.h +2 -2
  8. data/dist/ice/cpp/include/generated/Ice/EndpointTypes.h +2 -2
  9. data/dist/ice/cpp/include/generated/Ice/Identity.h +2 -2
  10. data/dist/ice/cpp/include/generated/Ice/Locator.h +9 -11
  11. data/dist/ice/cpp/include/generated/Ice/LocatorRegistry.h +2 -2
  12. data/dist/ice/cpp/include/generated/Ice/Metrics.h +7 -7
  13. data/dist/ice/cpp/include/generated/Ice/OperationMode.h +2 -2
  14. data/dist/ice/cpp/include/generated/Ice/Process.h +2 -2
  15. data/dist/ice/cpp/include/generated/Ice/PropertiesAdmin.h +2 -2
  16. data/dist/ice/cpp/include/generated/Ice/PropertyDict.h +2 -2
  17. data/dist/ice/cpp/include/generated/Ice/RemoteLogger.h +2 -2
  18. data/dist/ice/cpp/include/generated/Ice/ReplyStatus.h +8 -4
  19. data/dist/ice/cpp/include/generated/Ice/Router.h +7 -7
  20. data/dist/ice/cpp/include/generated/Ice/SliceChecksumDict.h +2 -2
  21. data/dist/ice/cpp/include/generated/Ice/Version.h +2 -2
  22. data/dist/ice/cpp/include/generated/IceDiscovery/Lookup.h +2 -2
  23. data/dist/ice/cpp/include/generated/IceLocatorDiscovery/Lookup.h +2 -2
  24. data/dist/ice/cpp/src/Ice/CollocatedRequestHandler.cpp +5 -3
  25. data/dist/ice/cpp/src/Ice/ConnectionI.cpp +27 -9
  26. data/dist/ice/cpp/src/Ice/ConnectionI.h +1 -1
  27. data/dist/ice/cpp/src/Ice/FileUtil.cpp +3 -67
  28. data/dist/ice/cpp/src/Ice/FileUtil.h +0 -3
  29. data/dist/ice/cpp/src/Ice/IPEndpointI.cpp +4 -0
  30. data/dist/ice/cpp/src/Ice/IncomingRequest.cpp +1 -1
  31. data/dist/ice/cpp/src/Ice/InputStream.cpp +28 -15
  32. data/dist/ice/cpp/src/Ice/LocalExceptions.cpp +6 -0
  33. data/dist/ice/cpp/src/Ice/OutgoingAsync.cpp +1 -1
  34. data/dist/ice/cpp/src/Ice/OutgoingResponse.cpp +127 -127
  35. data/dist/ice/cpp/src/Ice/OutgoingResponseInternal.h +21 -0
  36. data/dist/ice/cpp/src/Ice/OutputStream.cpp +46 -61
  37. data/dist/ice/cpp/src/Ice/PropertyNames.cpp +2 -1
  38. data/dist/ice/cpp/src/Ice/ProxyFunctions.cpp +4 -4
  39. data/dist/ice/cpp/src/Ice/Reference.cpp +15 -15
  40. data/dist/ice/cpp/src/Ice/ReferenceFactory.cpp +16 -13
  41. data/dist/ice/cpp/src/Ice/ResourceConfig.h +2 -2
  42. data/dist/ice/cpp/src/Ice/SSL/OpenSSLEngine.cpp +12 -11
  43. data/dist/ice/cpp/src/Ice/SSL/OpenSSLEngine.h +1 -2
  44. data/dist/ice/cpp/src/Ice/SSL/SSLEndpointI.cpp +1 -1
  45. data/dist/ice/cpp/src/Ice/SSL/SSLEngine.h +1 -4
  46. data/dist/ice/cpp/src/Ice/SSL/SchannelEngine.cpp +50 -43
  47. data/dist/ice/cpp/src/Ice/SSL/SchannelEngine.h +1 -5
  48. data/dist/ice/cpp/src/Ice/SSL/SchannelTransceiverI.cpp +9 -0
  49. data/dist/ice/cpp/src/Ice/SSL/SecureTransportEngine.cpp +107 -14
  50. data/dist/ice/cpp/src/Ice/SSL/SecureTransportEngine.h +7 -2
  51. data/dist/ice/cpp/src/Ice/TcpEndpointI.cpp +2 -2
  52. data/dist/ice/cpp/src/Ice/UdpEndpointI.cpp +2 -2
  53. data/dist/ice/cpp/src/Ice/WSAcceptor.cpp +8 -3
  54. data/dist/ice/cpp/src/Ice/WSAcceptor.h +5 -1
  55. data/dist/ice/cpp/src/Ice/WSEndpoint.cpp +45 -2
  56. data/dist/ice/cpp/src/Ice/WSTransceiver.cpp +118 -7
  57. data/dist/ice/cpp/src/Ice/WSTransceiver.h +12 -1
  58. data/dist/ice/cpp/src/Ice/generated/BuiltinSequences.cpp +2 -2
  59. data/dist/ice/cpp/src/Ice/generated/Context.cpp +2 -2
  60. data/dist/ice/cpp/src/Ice/generated/EndpointTypes.cpp +2 -2
  61. data/dist/ice/cpp/src/Ice/generated/Identity.cpp +2 -2
  62. data/dist/ice/cpp/src/Ice/generated/Locator.cpp +2 -2
  63. data/dist/ice/cpp/src/Ice/generated/LocatorRegistry.cpp +2 -2
  64. data/dist/ice/cpp/src/Ice/generated/Metrics.cpp +2 -2
  65. data/dist/ice/cpp/src/Ice/generated/OperationMode.cpp +2 -2
  66. data/dist/ice/cpp/src/Ice/generated/Process.cpp +2 -2
  67. data/dist/ice/cpp/src/Ice/generated/PropertiesAdmin.cpp +2 -2
  68. data/dist/ice/cpp/src/Ice/generated/PropertyDict.cpp +2 -2
  69. data/dist/ice/cpp/src/Ice/generated/RemoteLogger.cpp +2 -2
  70. data/dist/ice/cpp/src/Ice/generated/ReplyStatus.cpp +4 -2
  71. data/dist/ice/cpp/src/Ice/generated/Router.cpp +2 -2
  72. data/dist/ice/cpp/src/Ice/generated/SliceChecksumDict.cpp +2 -2
  73. data/dist/ice/cpp/src/Ice/generated/Version.cpp +2 -2
  74. data/dist/ice/cpp/src/IceDiscovery/generated/Lookup.cpp +2 -2
  75. data/dist/ice/cpp/src/IceLocatorDiscovery/generated/Lookup.cpp +2 -2
  76. data/dist/ice/cpp/src/Slice/DocCommentParser.cpp +6 -6
  77. data/dist/ice/cpp/src/Slice/DocCommentParser.h +4 -2
  78. data/dist/ice/cpp/src/Slice/MetadataValidation.cpp +24 -5
  79. data/dist/ice/cpp/src/Slice/MetadataValidation.h +3 -2
  80. data/dist/ice/cpp/src/Slice/Parser.cpp +117 -77
  81. data/dist/ice/cpp/src/Slice/Parser.h +19 -4
  82. data/dist/ice/cpp/src/Slice/Preprocessor.cpp +75 -19
  83. data/dist/ice/cpp/src/Slice/Preprocessor.h +0 -1
  84. data/dist/ice/cpp/src/Slice/SliceUtil.cpp +6 -58
  85. data/dist/ice/cpp/src/Slice/Util.h +0 -3
  86. data/dist/ice/cpp/src/slice2rb/RubyUtil.cpp +10 -8
  87. data/dist/ice/cpp/src/slice2rb/RubyUtil.h +10 -13
  88. data/dist/ice/slice/Ice/Identity.ice +3 -0
  89. data/dist/ice/slice/Ice/Locator.ice +6 -5
  90. data/dist/ice/slice/Ice/LocatorRegistry.ice +3 -0
  91. data/dist/ice/slice/Ice/Metrics.ice +1 -1
  92. data/dist/ice/slice/Ice/OperationMode.ice +8 -0
  93. data/dist/ice/slice/Ice/Process.ice +3 -0
  94. data/dist/ice/slice/Ice/ReplyStatus.ice +13 -0
  95. data/dist/lib/Glacier2/Metrics.rb +1 -1
  96. data/dist/lib/Glacier2/PermissionsVerifier.rb +3 -3
  97. data/dist/lib/Glacier2/Router.rb +8 -8
  98. data/dist/lib/Glacier2/SSLInfo.rb +1 -1
  99. data/dist/lib/Glacier2/Session.rb +15 -15
  100. data/dist/lib/Ice/BuiltinSequences.rb +1 -1
  101. data/dist/lib/Ice/Context.rb +1 -1
  102. data/dist/lib/Ice/EndpointTypes.rb +1 -1
  103. data/dist/lib/Ice/Identity.rb +1 -1
  104. data/dist/lib/Ice/LocalExceptions.rb +3 -0
  105. data/dist/lib/Ice/Locator.rb +5 -5
  106. data/dist/lib/Ice/LocatorRegistry.rb +4 -4
  107. data/dist/lib/Ice/Metrics.rb +7 -7
  108. data/dist/lib/Ice/OperationMode.rb +1 -1
  109. data/dist/lib/Ice/Process.rb +3 -3
  110. data/dist/lib/Ice/PropertiesAdmin.rb +4 -4
  111. data/dist/lib/Ice/PropertyDict.rb +1 -1
  112. data/dist/lib/Ice/ProxyFunctions.rb +8 -4
  113. data/dist/lib/Ice/RemoteLogger.rb +6 -6
  114. data/dist/lib/Ice/ReplyStatus.rb +3 -2
  115. data/dist/lib/Ice/Router.rb +5 -5
  116. data/dist/lib/Ice/SliceChecksumDict.rb +1 -1
  117. data/dist/lib/Ice/Version.rb +1 -1
  118. data/dist/lib/IceBox/ServiceManager.rb +8 -8
  119. data/dist/lib/IceGrid/Admin.rb +83 -83
  120. data/dist/lib/IceGrid/Descriptor.rb +1 -1
  121. data/dist/lib/IceGrid/Exception.rb +1 -1
  122. data/dist/lib/IceGrid/FileParser.rb +2 -2
  123. data/dist/lib/IceGrid/Registry.rb +13 -13
  124. data/dist/lib/IceGrid/Session.rb +6 -6
  125. data/dist/lib/IceGrid/UserAccountMapper.rb +2 -2
  126. data/dist/lib/IceStorm/IceStorm.rb +16 -16
  127. data/dist/lib/IceStorm/Metrics.rb +1 -1
  128. data/ice.gemspec +1 -1
  129. metadata +2 -1
@@ -93,13 +93,14 @@ IceInternal::ReferenceFactory::create(string_view str, const string& propertyPre
93
93
  return nullptr;
94
94
  }
95
95
 
96
- const string delim = " \t\r\n";
96
+ static constexpr const char* whitespace = " \t\r\n";
97
+ static constexpr const char* whitespaceOrSeparator = " \t\r\n:@";
97
98
 
98
- string s(str);
99
+ string s{str};
99
100
  string::size_type beg;
100
101
  string::size_type end = 0;
101
102
 
102
- beg = s.find_first_not_of(delim, end);
103
+ beg = s.find_first_not_of(whitespace, end);
103
104
  if (beg == string::npos)
104
105
  {
105
106
  throw ParseException(__FILE__, __LINE__, "no non-whitespace characters found in proxy string '" + s + "'");
@@ -117,7 +118,7 @@ IceInternal::ReferenceFactory::create(string_view str, const string& propertyPre
117
118
  }
118
119
  else if (end == 0)
119
120
  {
120
- end = s.find_first_of(delim + ":@", beg);
121
+ end = s.find_first_of(whitespaceOrSeparator, beg);
121
122
  if (end == string::npos)
122
123
  {
123
124
  end = s.size();
@@ -144,7 +145,7 @@ IceInternal::ReferenceFactory::create(string_view str, const string& propertyPre
144
145
  // a null proxy, but only if nothing follows the
145
146
  // quotes.
146
147
  //
147
- if (s.find_first_not_of(delim, end) != string::npos)
148
+ if (s.find_first_not_of(whitespace, end) != string::npos)
148
149
  {
149
150
  throw ParseException(__FILE__, __LINE__, "invalid characters after identity in proxy string '" + s + "'");
150
151
  }
@@ -167,7 +168,7 @@ IceInternal::ReferenceFactory::create(string_view str, const string& propertyPre
167
168
 
168
169
  while (true)
169
170
  {
170
- beg = s.find_first_not_of(delim, end);
171
+ beg = s.find_first_not_of(whitespace, end);
171
172
  if (beg == string::npos)
172
173
  {
173
174
  break;
@@ -178,7 +179,7 @@ IceInternal::ReferenceFactory::create(string_view str, const string& propertyPre
178
179
  break;
179
180
  }
180
181
 
181
- end = s.find_first_of(delim + ":@", beg);
182
+ end = s.find_first_of(whitespaceOrSeparator, beg);
182
183
  if (end == string::npos)
183
184
  {
184
185
  end = s.length();
@@ -204,7 +205,7 @@ IceInternal::ReferenceFactory::create(string_view str, const string& propertyPre
204
205
  // quotation marks.
205
206
  //
206
207
  string argument;
207
- string::size_type argumentBeg = s.find_first_not_of(delim, end);
208
+ string::size_type argumentBeg = s.find_first_not_of(whitespace, end);
208
209
  if (argumentBeg != string::npos)
209
210
  {
210
211
  if (s[argumentBeg] != '@' && s[argumentBeg] != ':' && s[argumentBeg] != '-')
@@ -220,7 +221,7 @@ IceInternal::ReferenceFactory::create(string_view str, const string& propertyPre
220
221
  }
221
222
  else if (end == 0)
222
223
  {
223
- end = s.find_first_of(delim + ":@", beg);
224
+ end = s.find_first_of(whitespaceOrSeparator, beg);
224
225
  if (end == string::npos)
225
226
  {
226
227
  end = s.size();
@@ -493,7 +494,7 @@ IceInternal::ReferenceFactory::create(string_view str, const string& propertyPre
493
494
  }
494
495
  case '@':
495
496
  {
496
- beg = s.find_first_not_of(delim, beg + 1);
497
+ beg = s.find_first_not_of(whitespace, beg + 1);
497
498
  if (beg == string::npos)
498
499
  {
499
500
  throw ParseException(__FILE__, __LINE__, "missing adapter id in proxy string '" + s + "'");
@@ -510,7 +511,7 @@ IceInternal::ReferenceFactory::create(string_view str, const string& propertyPre
510
511
  }
511
512
  else if (end == 0)
512
513
  {
513
- end = s.find_first_of(delim, beg);
514
+ end = s.find_first_of(whitespace, beg);
514
515
  if (end == string::npos)
515
516
  {
516
517
  end = s.size();
@@ -525,7 +526,7 @@ IceInternal::ReferenceFactory::create(string_view str, const string& propertyPre
525
526
  }
526
527
 
527
528
  // Check for trailing whitespace.
528
- if (end != string::npos && s.find_first_not_of(delim, end) != string::npos)
529
+ if (end != string::npos && s.find_first_not_of(whitespace, end) != string::npos)
529
530
  {
530
531
  throw ParseException(
531
532
  __FILE__,
@@ -610,7 +611,9 @@ IceInternal::ReferenceFactory::create(Identity ident, InputStream* s)
610
611
  vector<EndpointIPtr> endpoints;
611
612
  string adapterId;
612
613
 
613
- int32_t sz = s->readSize();
614
+ // Each endpoint occupies at least 8 bytes on the wire (a 2-byte type plus a 6-byte minimum
615
+ // encapsulation), so readAndCheckSeqSize rejects an oversized count before we allocate.
616
+ int32_t sz = s->readAndCheckSeqSize(8);
614
617
 
615
618
  if (sz > 0)
616
619
  {
@@ -5,8 +5,8 @@
5
5
 
6
6
  #include "winver.h"
7
7
 
8
- #define ICE_VERSION 3, 8, 1, 0
9
- #define ICE_STRING_VERSION "3.8.1\0"
8
+ #define ICE_VERSION 3, 8, 2, 0
9
+ #define ICE_STRING_VERSION "3.8.2\0"
10
10
  #define ICE_SO_VERSION "38\0"
11
11
  #define ICE_COMPANY_NAME "ZeroC, Inc.\0"
12
12
  #define ICE_COPYRIGHT "\251 ZeroC, Inc.\0"
@@ -72,7 +72,14 @@ namespace
72
72
 
73
73
  OpenSSL::SSLEngine::SSLEngine(const IceInternal::InstancePtr& instance) : Ice::SSL::SSLEngine(instance) {}
74
74
 
75
- OpenSSL::SSLEngine::~SSLEngine() = default;
75
+ OpenSSL::SSLEngine::~SSLEngine()
76
+ {
77
+ if (_ctx)
78
+ {
79
+ SSL_CTX_free(_ctx);
80
+ _ctx = nullptr;
81
+ }
82
+ }
76
83
 
77
84
  void
78
85
  OpenSSL::SSLEngine::initialize()
@@ -91,6 +98,10 @@ OpenSSL::SSLEngine::initialize()
91
98
  throw InitializationException(__FILE__, __LINE__, "IceSSL: unable to create SSL context:\n" + sslErrors());
92
99
  }
93
100
 
101
+ // Reject peer-initiated TLS renegotiation: it is a CPU-asymmetric denial-of-service primitive
102
+ // on TLS 1.2 and is removed entirely in TLS 1.3.
103
+ SSL_CTX_set_options(_ctx, SSL_OP_NO_RENEGOTIATION);
104
+
94
105
  // Check for a default directory. We look in this directory for files mentioned in the configuration.
95
106
  const string defaultDir = properties->getIceProperty("IceSSL.DefaultDir");
96
107
 
@@ -509,13 +520,3 @@ OpenSSL::SSLEngine::sslErrors() const
509
520
  {
510
521
  return getErrors();
511
522
  }
512
-
513
- void
514
- OpenSSL::SSLEngine::destroy()
515
- {
516
- if (_ctx)
517
- {
518
- SSL_CTX_free(_ctx);
519
- _ctx = nullptr;
520
- }
521
- }
@@ -17,10 +17,9 @@ namespace Ice::SSL::OpenSSL
17
17
  {
18
18
  public:
19
19
  SSLEngine(const IceInternal::InstancePtr&);
20
- ~SSLEngine();
20
+ ~SSLEngine() override;
21
21
 
22
22
  void initialize() final;
23
- void destroy() final;
24
23
  [[nodiscard]] std::string sslErrors() const;
25
24
  [[nodiscard]] std::string password() const { return _password; }
26
25
  [[nodiscard]] Ice::SSL::ClientAuthenticationOptions
@@ -232,7 +232,7 @@ Ice::SSL::EndpointI::endpoint(const IceInternal::EndpointIPtr& delEndp) const
232
232
  {
233
233
  if (delEndp.get() == _delegate.get())
234
234
  {
235
- return dynamic_pointer_cast<EndpointI>(const_cast<EndpointI*>(this)->shared_from_this());
235
+ return static_pointer_cast<EndpointI>(const_cast<EndpointI*>(this)->shared_from_this());
236
236
  }
237
237
  else
238
238
  {
@@ -23,7 +23,7 @@ namespace Ice::SSL
23
23
  {
24
24
  public:
25
25
  SSLEngine(const IceInternal::InstancePtr&);
26
- ~SSLEngine();
26
+ virtual ~SSLEngine();
27
27
 
28
28
  [[nodiscard]] Ice::LoggerPtr getLogger() const;
29
29
  [[nodiscard]] Ice::PropertiesPtr getProperties() const;
@@ -34,9 +34,6 @@ namespace Ice::SSL
34
34
  // Setup the engine.
35
35
  virtual void initialize() = 0;
36
36
 
37
- // Destroy the engine.
38
- virtual void destroy() = 0;
39
-
40
37
  // Verify peer certificate.
41
38
  virtual void verifyPeer(const ConnectionInfoPtr&) const;
42
39
 
@@ -743,6 +743,56 @@ Schannel::SSLEngine::SSLEngine(const IceInternal::InstancePtr& instance)
743
743
  {
744
744
  }
745
745
 
746
+ Schannel::SSLEngine::~SSLEngine()
747
+ {
748
+ // Best-effort cleanup. We catch every exception (e.g. std::bad_alloc from the per-cert vector
749
+ // allocation below) so nothing escapes the destructor and triggers std::terminate.
750
+ try
751
+ {
752
+ if (_chainEngine && _chainEngine != HCCE_CURRENT_USER && _chainEngine != HCCE_LOCAL_MACHINE)
753
+ {
754
+ CertFreeCertificateChainEngine(_chainEngine);
755
+ }
756
+
757
+ if (_rootStore)
758
+ {
759
+ CertCloseStore(_rootStore, 0);
760
+ }
761
+
762
+ for (vector<PCCERT_CONTEXT>::const_iterator i = _importedCerts.begin(); i != _importedCerts.end(); ++i)
763
+ {
764
+ // Retrieve the certificate CERT_KEY_PROV_INFO_PROP_ID property, we use the CRYPT_KEY_PROV_INFO data to
765
+ // remove the key set associated with the certificate.
766
+ DWORD length = 0;
767
+ if (!CertGetCertificateContextProperty(*i, CERT_KEY_PROV_INFO_PROP_ID, 0, &length))
768
+ {
769
+ continue;
770
+ }
771
+ vector<char> buf(length);
772
+ if (!CertGetCertificateContextProperty(*i, CERT_KEY_PROV_INFO_PROP_ID, &buf[0], &length))
773
+ {
774
+ continue;
775
+ }
776
+ CRYPT_KEY_PROV_INFO* key = reinterpret_cast<CRYPT_KEY_PROV_INFO*>(&buf[0]);
777
+ HCRYPTPROV prov = 0;
778
+ CryptAcquireContextW(&prov, key->pwszContainerName, key->pwszProvName, key->dwProvType, CRYPT_DELETEKEYSET);
779
+ }
780
+
781
+ for (vector<PCCERT_CONTEXT>::const_iterator i = _allCerts.begin(); i != _allCerts.end(); ++i)
782
+ {
783
+ CertFreeCertificateContext(*i);
784
+ }
785
+
786
+ for (vector<HCERTSTORE>::const_iterator i = _stores.begin(); i != _stores.end(); ++i)
787
+ {
788
+ CertCloseStore(*i, 0);
789
+ }
790
+ }
791
+ catch (...)
792
+ {
793
+ }
794
+ }
795
+
746
796
  void
747
797
  Schannel::SSLEngine::initialize()
748
798
  {
@@ -1210,49 +1260,6 @@ Schannel::SSLEngine::getCipherName(ALG_ID cipher) const
1210
1260
  }
1211
1261
  }
1212
1262
 
1213
- void
1214
- Schannel::SSLEngine::destroy()
1215
- {
1216
- if (_chainEngine && _chainEngine != HCCE_CURRENT_USER && _chainEngine != HCCE_LOCAL_MACHINE)
1217
- {
1218
- CertFreeCertificateChainEngine(_chainEngine);
1219
- }
1220
-
1221
- if (_rootStore)
1222
- {
1223
- CertCloseStore(_rootStore, 0);
1224
- }
1225
-
1226
- for (vector<PCCERT_CONTEXT>::const_iterator i = _importedCerts.begin(); i != _importedCerts.end(); ++i)
1227
- {
1228
- // Retrieve the certificate CERT_KEY_PROV_INFO_PROP_ID property, we use the CRYPT_KEY_PROV_INFO data to remove
1229
- // the key set associated with the certificate.
1230
- DWORD length = 0;
1231
- if (!CertGetCertificateContextProperty(*i, CERT_KEY_PROV_INFO_PROP_ID, 0, &length))
1232
- {
1233
- continue;
1234
- }
1235
- vector<char> buf(length);
1236
- if (!CertGetCertificateContextProperty(*i, CERT_KEY_PROV_INFO_PROP_ID, &buf[0], &length))
1237
- {
1238
- continue;
1239
- }
1240
- CRYPT_KEY_PROV_INFO* key = reinterpret_cast<CRYPT_KEY_PROV_INFO*>(&buf[0]);
1241
- HCRYPTPROV prov = 0;
1242
- CryptAcquireContextW(&prov, key->pwszContainerName, key->pwszProvName, key->dwProvType, CRYPT_DELETEKEYSET);
1243
- }
1244
-
1245
- for (vector<PCCERT_CONTEXT>::const_iterator i = _allCerts.begin(); i != _allCerts.end(); ++i)
1246
- {
1247
- CertFreeCertificateContext(*i);
1248
- }
1249
-
1250
- for (vector<HCERTSTORE>::const_iterator i = _stores.begin(); i != _stores.end(); ++i)
1251
- {
1252
- CertCloseStore(*i, 0);
1253
- }
1254
- }
1255
-
1256
1263
  Ice::SSL::ClientAuthenticationOptions
1257
1264
  Schannel::SSLEngine::createClientAuthenticationOptions(const string& host) const
1258
1265
  {
@@ -22,17 +22,13 @@ namespace Ice::SSL::Schannel
22
22
  {
23
23
  public:
24
24
  SSLEngine(const IceInternal::InstancePtr&);
25
+ ~SSLEngine() override;
25
26
 
26
27
  //
27
28
  // Setup the engine.
28
29
  //
29
30
  void initialize() final;
30
31
 
31
- //
32
- // Destroy the engine.
33
- //
34
- void destroy() final;
35
-
36
32
  [[nodiscard]] std::string getCipherName(ALG_ID) const;
37
33
 
38
34
  [[nodiscard]] Ice::SSL::ClientAuthenticationOptions
@@ -552,6 +552,15 @@ Schannel::TransceiverI::decryptMessage(IceInternal::Buffer& buffer)
552
552
  }
553
553
  else if (err == SEC_I_RENEGOTIATE)
554
554
  {
555
+ if (_incoming)
556
+ {
557
+ // Reject peer-initiated TLS renegotiation on the server side: it is a CPU-asymmetric
558
+ // denial-of-service primitive on TLS 1.2 and is removed entirely in TLS 1.3.
559
+ throw ProtocolException(
560
+ __FILE__,
561
+ __LINE__,
562
+ "SSL transport: peer-initiated TLS renegotiation is not supported on the server side.");
563
+ }
555
564
  if (_sslConnectionRenegotiating)
556
565
  {
557
566
  throw ProtocolException(
@@ -9,10 +9,17 @@
9
9
  #include "Ice/Logger.h"
10
10
  #include "Ice/Properties.h"
11
11
  #include "Ice/SSL/SSLException.h"
12
+ #include "Ice/UUID.h"
12
13
  #include "SSLEngine.h"
13
14
  #include "SSLUtil.h"
14
15
  #include "SecureTransportUtil.h"
15
16
 
17
+ #include <cerrno>
18
+ #include <climits>
19
+ #include <cstring>
20
+ #include <unistd.h>
21
+ #include <vector>
22
+
16
23
  // Disable deprecation warnings from SecureTransport APIs
17
24
  #include "../DisableWarnings.h"
18
25
 
@@ -547,6 +554,43 @@ namespace
547
554
  }
548
555
  }
549
556
  }
557
+
558
+ #if defined(ICE_USE_SECURE_TRANSPORT_MACOS)
559
+ // Creates a private temporary directory to hold a short-lived keychain, and returns its path.
560
+ // Uses confstr(_CS_DARWIN_USER_TEMP_DIR) rather than $TMPDIR so the location can't be
561
+ // redirected through the process environment.
562
+ string createTemporaryKeychainDirectory()
563
+ {
564
+ char base[PATH_MAX];
565
+ size_t len = confstr(_CS_DARWIN_USER_TEMP_DIR, base, sizeof(base));
566
+ if (len == 0 || len > sizeof(base))
567
+ {
568
+ int error = errno;
569
+
570
+ ostringstream os;
571
+ os << "SSL transport: confstr(_CS_DARWIN_USER_TEMP_DIR) failed";
572
+ if (error != 0)
573
+ {
574
+ os << ": " << strerror(error);
575
+ }
576
+ throw InitializationException(__FILE__, __LINE__, os.str());
577
+ }
578
+
579
+ string tmpl = string{base} + "ice-keychain-XXXXXX";
580
+ vector<char> buffer(tmpl.begin(), tmpl.end());
581
+ buffer.push_back('\0');
582
+
583
+ char* dir = mkdtemp(buffer.data());
584
+ if (dir == nullptr)
585
+ {
586
+ int error = errno;
587
+ ostringstream os;
588
+ os << "SSL transport: mkdtemp failed: " << strerror(error);
589
+ throw InitializationException(__FILE__, __LINE__, os.str());
590
+ }
591
+ return dir;
592
+ }
593
+ #endif
550
594
  }
551
595
 
552
596
  SecureTransport::SSLEngine::SSLEngine(const IceInternal::InstancePtr& instance)
@@ -556,7 +600,25 @@ SecureTransport::SSLEngine::SSLEngine(const IceInternal::InstancePtr& instance)
556
600
  {
557
601
  }
558
602
 
559
- SecureTransport::SSLEngine::~SSLEngine() = default;
603
+ SecureTransport::SSLEngine::~SSLEngine()
604
+ {
605
+ #if defined(ICE_USE_SECURE_TRANSPORT_MACOS)
606
+ if (!_temporaryKeychainDir.empty())
607
+ {
608
+ // Remove the temporary keychain and its enclosing directory created by initialize().
609
+ // The cleanup lives in the destructor (not destroy()) so it also runs when initialize()
610
+ // throws after the directory has been created.
611
+ _chain.reset();
612
+ const string keychainPath = _temporaryKeychainDir + "/ice.keychain";
613
+ UniqueRef<SecKeychainRef> keychain;
614
+ if (SecKeychainOpen(keychainPath.c_str(), &keychain.get()) == noErr && keychain.get())
615
+ {
616
+ SecKeychainDelete(keychain.get());
617
+ }
618
+ rmdir(_temporaryKeychainDir.c_str());
619
+ }
620
+ #endif
621
+ }
560
622
 
561
623
  //
562
624
  // Setup the engine.
@@ -636,6 +698,18 @@ SecureTransport::SSLEngine::initialize()
636
698
  keyFile = *resolved;
637
699
  }
638
700
 
701
+ #if defined(ICE_USE_SECURE_TRANSPORT_MACOS)
702
+ if (keychain.empty())
703
+ {
704
+ // Import the certificate into a temporary keychain rather than the user's login keychain.
705
+ // A private key in the login keychain cannot complete a forward-secret (ECDHE) handshake
706
+ // on the server side. The keychain and its enclosing directory are removed by the destructor.
707
+ _temporaryKeychainDir = createTemporaryKeychainDirectory();
708
+ keychain = _temporaryKeychainDir + "/ice.keychain";
709
+ keychainPassword = Ice::generateUUID();
710
+ }
711
+ #endif
712
+
639
713
  try
640
714
  {
641
715
  _chain.reset(loadCertificateChain(certFile, keyFile, keychain, keychainPassword, password));
@@ -651,14 +725,6 @@ SecureTransport::SSLEngine::initialize()
651
725
  }
652
726
  }
653
727
 
654
- //
655
- // Destroy the engine.
656
- //
657
- void
658
- SecureTransport::SSLEngine::destroy()
659
- {
660
- }
661
-
662
728
  ClientAuthenticationOptions
663
729
  SecureTransport::SSLEngine::createClientAuthenticationOptions(const string& host) const
664
730
  {
@@ -721,15 +787,15 @@ SecureTransport::SSLEngine::createServerAuthenticationOptions() const
721
787
  SSLContextRef
722
788
  SecureTransport::SSLEngine::newContext(bool incoming) const
723
789
  {
724
- SSLContextRef ssl =
725
- SSLCreateContext(kCFAllocatorDefault, incoming ? kSSLServerSide : kSSLClientSide, kSSLStreamType);
726
- if (!ssl)
790
+ UniqueRef<SSLContextRef> ssl(
791
+ SSLCreateContext(kCFAllocatorDefault, incoming ? kSSLServerSide : kSSLClientSide, kSSLStreamType));
792
+ if (!ssl.get())
727
793
  {
728
794
  throw SecurityException(__FILE__, __LINE__, "SSL transport: unable to create SSL context");
729
795
  }
730
796
 
731
797
  OSStatus err = SSLSetSessionOption(
732
- ssl,
798
+ ssl.get(),
733
799
  incoming ? kSSLSessionOptionBreakOnClientAuth : kSSLSessionOptionBreakOnServerAuth,
734
800
  true);
735
801
 
@@ -741,7 +807,34 @@ SecureTransport::SSLEngine::newContext(bool incoming) const
741
807
  "SSL transport: error while setting SSL option:\n" + sslErrorToString(err));
742
808
  }
743
809
 
744
- return ssl;
810
+ // Require TLS 1.2 or later. SecureTransport otherwise negotiates down to TLS 1.0 on macOS.
811
+ err = SSLSetProtocolVersionMin(ssl.get(), kTLSProtocol12);
812
+ if (err != noErr)
813
+ {
814
+ throw SecurityException(
815
+ __FILE__,
816
+ __LINE__,
817
+ "SSL transport: error while setting the minimum protocol version:\n" + sslErrorToString(err));
818
+ }
819
+
820
+ // Enable only forward-secret cipher suites: the Mozilla "Intermediate" recommendation for TLS 1.2
821
+ // intersected with what SecureTransport can negotiate — ECDHE key exchange with AES-GCM.
822
+ // SecureTransport's own default set also includes static-RSA suites (no forward secrecy) and 3DES.
823
+ const SSLCipherSuite ciphers[] = {
824
+ TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
825
+ TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
826
+ TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
827
+ TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384};
828
+ err = SSLSetEnabledCiphers(ssl.get(), ciphers, sizeof(ciphers) / sizeof(SSLCipherSuite));
829
+ if (err != noErr)
830
+ {
831
+ throw SecurityException(
832
+ __FILE__,
833
+ __LINE__,
834
+ "SSL transport: error while setting ciphers:\n" + sslErrorToString(err));
835
+ }
836
+
837
+ return ssl.release();
745
838
  }
746
839
 
747
840
  bool
@@ -20,10 +20,9 @@ namespace Ice::SSL::SecureTransport
20
20
  {
21
21
  public:
22
22
  SSLEngine(const IceInternal::InstancePtr&);
23
- ~SSLEngine();
23
+ ~SSLEngine() override;
24
24
 
25
25
  void initialize() final;
26
- void destroy() final;
27
26
 
28
27
  [[nodiscard]] Ice::SSL::ClientAuthenticationOptions
29
28
  createClientAuthenticationOptions(const std::string& host) const final;
@@ -37,6 +36,12 @@ namespace Ice::SSL::SecureTransport
37
36
  private:
38
37
  IceInternal::UniqueRef<CFArrayRef> _certificateAuthorities;
39
38
  IceInternal::UniqueRef<CFArrayRef> _chain;
39
+
40
+ # if defined(ICE_USE_SECURE_TRANSPORT_MACOS)
41
+ // Path of the temporary directory holding the imported certificate's keychain, removed by the destructor.
42
+ // Empty when IceSSL.Keychain is set or no certificate is configured.
43
+ std::string _temporaryKeychainDir;
44
+ # endif
40
45
  };
41
46
  }
42
47
  #endif
@@ -169,7 +169,7 @@ AcceptorPtr
169
169
  IceInternal::TcpEndpointI::acceptor(const string&, const optional<Ice::SSL::ServerAuthenticationOptions>&) const
170
170
  {
171
171
  return make_shared<TcpAcceptor>(
172
- dynamic_pointer_cast<TcpEndpointI>(const_cast<TcpEndpointI*>(this)->shared_from_this()),
172
+ static_pointer_cast<TcpEndpointI>(const_cast<TcpEndpointI*>(this)->shared_from_this()),
173
173
  _instance,
174
174
  _host,
175
175
  _port);
@@ -181,7 +181,7 @@ IceInternal::TcpEndpointI::endpoint(const TcpAcceptorPtr& acceptor) const
181
181
  int port = acceptor->effectivePort();
182
182
  if (_port == port)
183
183
  {
184
- return dynamic_pointer_cast<TcpEndpointI>(const_cast<TcpEndpointI*>(this)->shared_from_this());
184
+ return static_pointer_cast<TcpEndpointI>(const_cast<TcpEndpointI*>(this)->shared_from_this());
185
185
  }
186
186
  else
187
187
  {
@@ -162,7 +162,7 @@ TransceiverPtr
162
162
  IceInternal::UdpEndpointI::transceiver() const
163
163
  {
164
164
  return make_shared<UdpTransceiver>(
165
- dynamic_pointer_cast<UdpEndpointI>(const_cast<UdpEndpointI*>(this)->shared_from_this()),
165
+ static_pointer_cast<UdpEndpointI>(const_cast<UdpEndpointI*>(this)->shared_from_this()),
166
166
  _instance,
167
167
  _host,
168
168
  _port,
@@ -181,7 +181,7 @@ IceInternal::UdpEndpointI::endpoint(const UdpTransceiverPtr& transceiver) const
181
181
  int port = transceiver->effectivePort();
182
182
  if (port == _port)
183
183
  {
184
- return dynamic_pointer_cast<UdpEndpointI>(const_cast<UdpEndpointI*>(this)->shared_from_this());
184
+ return static_pointer_cast<UdpEndpointI>(const_cast<UdpEndpointI*>(this)->shared_from_this());
185
185
  }
186
186
  else
187
187
  {
@@ -56,7 +56,7 @@ IceInternal::WSAcceptor::accept()
56
56
  // WebSocket handshaking is performed in TransceiverI::initialize, since
57
57
  // accept must not block.
58
58
  //
59
- return make_shared<WSTransceiver>(_instance, _delegate->accept());
59
+ return make_shared<WSTransceiver>(_instance, _delegate->accept(), _allowedOrigins);
60
60
  }
61
61
 
62
62
  string
@@ -77,10 +77,15 @@ IceInternal::WSAcceptor::toDetailedString() const
77
77
  return _delegate->toDetailedString();
78
78
  }
79
79
 
80
- IceInternal::WSAcceptor::WSAcceptor(WSEndpointPtr endpoint, ProtocolInstancePtr instance, AcceptorPtr del)
80
+ IceInternal::WSAcceptor::WSAcceptor(
81
+ WSEndpointPtr endpoint,
82
+ ProtocolInstancePtr instance,
83
+ AcceptorPtr del,
84
+ set<string> allowedOrigins)
81
85
  : _endpoint(std::move(endpoint)),
82
86
  _instance(std::move(instance)),
83
- _delegate(std::move(del))
87
+ _delegate(std::move(del)),
88
+ _allowedOrigins(std::move(allowedOrigins))
84
89
  {
85
90
  }
86
91
 
@@ -9,6 +9,9 @@
9
9
  #include "ProtocolInstance.h"
10
10
  #include "TransceiverF.h"
11
11
 
12
+ #include <set>
13
+ #include <string>
14
+
12
15
  namespace IceInternal
13
16
  {
14
17
  class WSEndpoint;
@@ -16,7 +19,7 @@ namespace IceInternal
16
19
  class WSAcceptor final : public Acceptor, public NativeInfo
17
20
  {
18
21
  public:
19
- WSAcceptor(WSEndpointPtr, ProtocolInstancePtr, AcceptorPtr);
22
+ WSAcceptor(WSEndpointPtr, ProtocolInstancePtr, AcceptorPtr, std::set<std::string> allowedOrigins);
20
23
  ~WSAcceptor() override;
21
24
  NativeInfoPtr getNativeInfo() final;
22
25
  #if defined(ICE_USE_IOCP)
@@ -40,6 +43,7 @@ namespace IceInternal
40
43
  WSEndpointPtr _endpoint;
41
44
  const ProtocolInstancePtr _instance;
42
45
  const AcceptorPtr _delegate;
46
+ const std::set<std::string> _allowedOrigins;
43
47
  };
44
48
  }
45
49