diff options
Diffstat (limited to 'cpp')
130 files changed, 3236 insertions, 3901 deletions
diff --git a/cpp/allTests.py b/cpp/allTests.py index 933d634552c..619e67c5427 100755 --- a/cpp/allTests.py +++ b/cpp/allTests.py @@ -74,7 +74,7 @@ tests = [ ("Ice/plugin", ["core", "nomingw"]), ("Ice/hash", ["once"]), ("Ice/admin", ["core", "noipv6"]), - ("Ice/metrics", ["core", "nossl", "nows", "noipv6", "nocompress", "nomingw", "nosocks"]), + ("Ice/metrics", ["core", "nows", "noipv6", "nocompress", "nomingw", "nosocks"]), ("Ice/enums", ["once", "bt"]), ("Ice/logger", ["once"]), ("Ice/networkProxy", ["core", "noipv6", "nosocks"]), diff --git a/cpp/config/Make.xcodesdk.rules b/cpp/config/Make.xcodesdk.rules index 11fb34bdef3..097b1249f9e 100644 --- a/cpp/config/Make.xcodesdk.rules +++ b/cpp/config/Make.xcodesdk.rules @@ -21,7 +21,7 @@ xcodesdk_installdir = $(if $(filter %/build,$5),xcodesdk,$(if $(is-iostest-progr xcodesdk_targetrule = $(if $(is-iostest-program),iostest,$(if $(filter-out program,$($1_target)),static)) xcodesdk_components = Ice IceSSL Glacier2 IceStorm IceGrid IceDiscovery IceLocatorDiscovery TestCommon -xcodesdk_projects = test/Ice/% test/IceDiscovery/simple +xcodesdk_projects = test/Ice/% test/IceDiscovery/simple test/IceSSL/configuration xcodesdk_excludes = $(addprefix test/Ice/,background \ faultTolerance \ gc \ diff --git a/cpp/include/Ice/MetricsObserverI.h b/cpp/include/Ice/MetricsObserverI.h index 78237a96eac..39b1f08f61b 100644 --- a/cpp/include/Ice/MetricsObserverI.h +++ b/cpp/include/Ice/MetricsObserverI.h @@ -183,7 +183,7 @@ protected: virtual std::string operator()(const Helper* r) const { O o = (r->*_getFn)(); - I* v = dynamic_cast<I*>(IceInternal::ReferenceWrapper<O>::get(o)); + I* v = dynamicCast<I>(IceInternal::ReferenceWrapper<O>::get(o)); if(v) { return toString(v->*_member); @@ -212,7 +212,7 @@ protected: virtual std::string operator()(const Helper* r) const { O o = (r->*_getFn)(); - I* v = dynamic_cast<I*>(IceInternal::ReferenceWrapper<O>::get(o)); + I* v = dynamicCast<I>(IceInternal::ReferenceWrapper<O>::get(o)); if(v) { return toString((v->*_memberFn)()); @@ -229,6 +229,40 @@ protected: Y (I::*_memberFn)() const; }; + template<typename I, typename V> static I* + dynamicCast(V* v) + { + return dynamic_cast<I*>(v); + } + + template<typename I> static I* + dynamicCast(Ice::EndpointInfo* v) + { + for(Ice::EndpointInfo* info = v; info; info = info->underlying.get()) + { + I* i = dynamic_cast<I*>(info); + if(i) + { + return i; + } + } + return 0; + } + + template<typename I> static I* + dynamicCast(Ice::ConnectionInfo* v) + { + for(Ice::ConnectionInfo* info = v; info; info = info->underlying.get()) + { + I* i = dynamic_cast<I*>(info); + if(i) + { + return i; + } + } + return 0; + } + template<typename I> static std::string toString(const I& v) { @@ -242,7 +276,7 @@ protected: { return p->ice_toString(); } - + static const std::string& toString(const std::string& s) { diff --git a/cpp/include/Ice/RegisterPlugins.h b/cpp/include/Ice/RegisterPlugins.h index 501811453e8..9d02facefdc 100644 --- a/cpp/include/Ice/RegisterPlugins.h +++ b/cpp/include/Ice/RegisterPlugins.h @@ -34,10 +34,6 @@ namespace Ice // inconsistent DLL linkage errors on Windows. // -#ifndef ICE_API_EXPORTS -ICE_PLUGIN_REGISTER_DECLSPEC_IMPORT void registerIceStringConverter(bool = true); -#endif - #ifndef ICE_SSL_API_EXPORTS ICE_PLUGIN_REGISTER_DECLSPEC_IMPORT void registerIceSSL(bool = true); #endif @@ -54,6 +50,11 @@ ICE_PLUGIN_REGISTER_DECLSPEC_IMPORT void registerIceLocatorDiscovery(bool = true ICE_PLUGIN_REGISTER_DECLSPEC_IMPORT void registerIceBT(bool = true); #endif +#if defined(__APPLE__) && TARGET_OS_IPHONE != 0 +#ifndef ICE_IAP_API_EXPORTS +ICE_PLUGIN_REGISTER_DECLSPEC_IMPORT void registerIceIAP(bool = true); +#endif +#endif #if defined(_MSC_VER) && !defined(ICE_BUILDING_SRC) # pragma comment(lib, ICE_LIBNAME("IceDiscovery")) diff --git a/cpp/include/IceIAP/IceIAP.h b/cpp/include/IceIAP/IceIAP.h new file mode 100644 index 00000000000..c494dc799e0 --- /dev/null +++ b/cpp/include/IceIAP/IceIAP.h @@ -0,0 +1,18 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2016 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef ICE_IAP_ICE_IAP_H +#define ICE_IAP_ICE_IAP_H + +#include <IceUtil/PushDisableWarnings.h> +#include <IceIAP/EndpointInfo.h> +#include <IceIAP/ConnectionInfo.h> +#include <IceUtil/PopDisableWarnings.h> + +#endif diff --git a/cpp/include/IceSSL/Config.h b/cpp/include/IceSSL/Config.h index db8648bdda7..61794c499ae 100644 --- a/cpp/include/IceSSL/Config.h +++ b/cpp/include/IceSSL/Config.h @@ -25,8 +25,15 @@ #if defined(__APPLE__) # define ICE_USE_SECURE_TRANSPORT 1 +#if defined(__APPLE__) && TARGET_OS_IPHONE != 0 +# define ICE_USE_SECURE_TRANSPORT_IOS 1 +#else +# define ICE_USE_SECURE_TRANSPORT_MACOS 1 +#endif #elif defined(_WIN32) -# define ICE_USE_SCHANNEL 1 +# if !defined(ICE_OS_WINRT) +# define ICE_USE_SCHANNEL 1 +# endif #else # define ICE_USE_OPENSSL 1 #endif diff --git a/cpp/include/IceSSL/IceSSL.h b/cpp/include/IceSSL/IceSSL.h index 4f837df8920..a4e8719b6dc 100644 --- a/cpp/include/IceSSL/IceSSL.h +++ b/cpp/include/IceSSL/IceSSL.h @@ -12,7 +12,7 @@ #include <IceUtil/PushDisableWarnings.h> #include <IceUtil/Config.h> -#if !defined(ICE_OS_WINRT) && (!defined(__APPLE__) || TARGET_OS_IPHONE == 0) +#if !defined(ICE_OS_WINRT) # include <IceSSL/Plugin.h> #endif #include <IceSSL/EndpointInfo.h> diff --git a/cpp/include/IceSSL/Plugin.h b/cpp/include/IceSSL/Plugin.h index 91c25e0e1a2..6987dfa71ca 100644 --- a/cpp/include/IceSSL/Plugin.h +++ b/cpp/include/IceSSL/Plugin.h @@ -21,13 +21,16 @@ // For struct sockaddr_storage #ifdef _WIN32 +#ifndef ICE_OS_WINRT # include <winsock2.h> +#endif #else # include <sys/socket.h> #endif #if defined(ICE_USE_SECURE_TRANSPORT) # include <CoreFoundation/CFError.h> +# include <Security/Security.h> #elif defined(ICE_USE_SCHANNEL) # include <wincrypt.h> #endif @@ -50,49 +53,26 @@ // connections. // typedef struct ssl_ctx_st SSL_CTX; +typedef struct X509_name_st X509NAME; -// -// Pointer to an opaque certificate object. X509_st is the OpenSSL -// type that represents a certificate. -// typedef struct x509_st* X509CertificateRef; - -// -// EVP_PKEY is the OpenSSL type that represents a public key. -// typedef struct evp_pkey_st* KeyRef; -// -// Type that represents an X509 distinguished name -// -typedef struct X509_name_st X509NAME; - #elif defined(ICE_USE_SECURE_TRANSPORT) -// -// Pointer to an opaque certificate object. -// -struct OpaqueSecCertificateRef; -typedef struct OpaqueSecCertificateRef* X509CertificateRef; - -// -// Pointer to an opaque key object. -// -struct OpaqueSecKeyRef; -typedef struct OpaqueSecKeyRef* KeyRef; +typedef SecCertificateRef X509CertificateRef; +typedef SecKeyRef KeyRef; #elif defined(ICE_USE_SCHANNEL) -// -// Pointer to an opaque certificate object. -// typedef CERT_SIGNED_CONTENT_INFO* X509CertificateRef; - -// -// Pointer to an opaque key object. -// typedef CERT_PUBLIC_KEY_INFO* KeyRef; +#elif defined(ICE_OS_WINRT) + +typedef Windows::Security::Cryptography::Certificates::Certificate^ X509CertificateRef; +typedef Windows::Security::Cryptography::Core::CryptographicKey^ KeyRef; + #endif namespace IceSSL @@ -232,6 +212,10 @@ public: DistinguishedName(X509NAME*); #endif +#if defined(__APPLE__) && TARGET_OS_IPHONE != 0 + DistinguishedName(CFDataRef); +#endif + // // Create a DistinguishedName from a string encoded using // the rules in RFC2253. @@ -288,8 +272,8 @@ public: // Construct a certificate using a native certificate. // // The Certificate class assumes ownership of the given native - // certificate. // + // certificate. Certificate(X509CertificateRef); ~Certificate(); @@ -344,6 +328,8 @@ public: // std::string encode() const; +#if !defined(__APPLE__) || TARGET_OS_IPHONE == 0 + // // Checks that the certificate is currently valid, that is, the current // date falls between the validity period given in the certificate. @@ -364,6 +350,7 @@ public: // Get the not-before validity time. // IceUtil::Time getNotBefore() const; +#endif // // Get the serial number. This is an arbitrarily large number. @@ -385,6 +372,7 @@ public: // DistinguishedName getIssuerDN() const; +#if !defined(__APPLE__) || TARGET_OS_IPHONE == 0 // // Get the values in the issuer's alternative names extension. // @@ -412,16 +400,19 @@ public: // X509* certificate to obtain these values. // std::vector<std::pair<int, std::string> > getIssuerAlternativeNames(); +#endif // // Get the subject's distinguished name (DN). // DistinguishedName getSubjectDN() const; +#if !defined(__APPLE__) || TARGET_OS_IPHONE == 0 // // See the comment for getIssuerAlternativeNames. // std::vector<std::pair<int, std::string> > getSubjectAlternativeNames(); +#endif // // Retrieve the certificate version number. @@ -453,6 +444,13 @@ private: #ifdef ICE_USE_SCHANNEL CERT_INFO* _certInfo; #endif +#if defined(__APPLE__) && TARGET_OS_IPHONE != 0 + void initializeAttributes() const; + mutable CFDataRef _subject; + mutable CFDataRef _issuer; + mutable std::string _serial; + mutable int _version; +#endif }; // @@ -473,23 +471,6 @@ public: ICE_DEFINE_PTR(NativeConnectionInfoPtr, NativeConnectionInfo); // -// WSSNativeConnectionInfo is an extension of IceSSL::WSSConnectionInfo -// that provides access to native certificates. -// -class ICE_SSL_API WSSNativeConnectionInfo : public WSSConnectionInfo -{ -public: - - // - // The certificate chain. This may be empty if the peer did not - // supply a certificate. The peer's certificate (if any) is the - // first one in the chain. - // - std::vector<CertificatePtr> nativeCerts; -}; -ICE_DEFINE_PTR(WSSNativeConnectionInfoPtr, WSSNativeConnectionInfo); - -// // An application can customize the certificate verification process // by implementing the CertificateVerifier interface. // diff --git a/cpp/msbuild/ice.proj b/cpp/msbuild/ice.proj index be7fdcdbda9..c300162a7fd 100644 --- a/cpp/msbuild/ice.proj +++ b/cpp/msbuild/ice.proj @@ -125,7 +125,7 @@ </DistSolution> </ItemGroup> - <!-- ARM Buidls require Win32 for the Slice translators --> + <!-- ARM Builds require Win32 for the Slice translators --> <ItemGroup Condition="'$(Platform)' == 'ARM'"> <DistSolution Include="ice.$(DefaultPlatformToolset).sln"> <Properties>Configuration=$(Configuration);Platform=Win32</Properties> diff --git a/cpp/src/Glacier2/SessionRouterI.cpp b/cpp/src/Glacier2/SessionRouterI.cpp index 89508705051..4d46d210726 100644 --- a/cpp/src/Glacier2/SessionRouterI.cpp +++ b/cpp/src/Glacier2/SessionRouterI.cpp @@ -1,3 +1,4 @@ + // ********************************************************************** // // Copyright (c) 2003-2016 ZeroC, Inc. All rights reserved. @@ -90,6 +91,21 @@ private: const SessionRouterIPtr _router; const Ice::ConnectionPtr _connection; }; + +Ice::IPConnectionInfoPtr +getIPConnectionInfo(const Ice::ConnectionInfoPtr& info) +{ + for(Ice::ConnectionInfoPtr p = info; p; p = p->underlying) + { + Ice::IPConnectionInfoPtr ipInfo = Ice::IPConnectionInfoPtr::dynamicCast(p); + if(ipInfo) + { + return ipInfo; + } + } + return ICE_NULLPTR; +} + } namespace Glacier2 @@ -443,7 +459,7 @@ CreateSession::CreateSession(const SessionRouterIPtr& sessionRouter, const strin { _context["_con.type"] = current.con->type(); { - Ice::IPConnectionInfoPtr info = Ice::IPConnectionInfoPtr::dynamicCast(current.con->getInfo()); + Ice::IPConnectionInfoPtr info = getIPConnectionInfo(current.con->getInfo()); if(info) { ostringstream os; @@ -832,10 +848,11 @@ SessionRouterI::createSessionFromSecureConnection_async( amdCB->ice_exception(PermissionDeniedException("not ssl connection")); return; } - sslinfo.remotePort = info->remotePort; - sslinfo.remoteHost = info->remoteAddress; - sslinfo.localPort = info->localPort; - sslinfo.localHost = info->localAddress; + Ice::IPConnectionInfoPtr ipInfo = getIPConnectionInfo(info); + sslinfo.remotePort = ipInfo->remotePort; + sslinfo.remoteHost = ipInfo->remoteAddress; + sslinfo.localPort = ipInfo->localPort; + sslinfo.localHost = ipInfo->localAddress; sslinfo.cipher = info->cipher; sslinfo.certs = info->certs; if(info->certs.size() > 0) diff --git a/cpp/src/Ice/ConnectionI.cpp b/cpp/src/Ice/ConnectionI.cpp index 4f038bea61f..2abec6e1a82 100644 --- a/cpp/src/Ice/ConnectionI.cpp +++ b/cpp/src/Ice/ConnectionI.cpp @@ -3642,9 +3642,15 @@ Ice::ConnectionI::initConnectionInfo() const { _info = ICE_MAKE_SHARED(ConnectionInfo); } - _info->connectionId = _endpoint->connectionId(); - _info->incoming = _connector == 0; - _info->adapterName = _adapter ? _adapter->getName() : string(); + + Ice::ConnectionInfoPtr info = _info; + while(info) + { + info->connectionId = _endpoint->connectionId(); + info->incoming = _connector == 0; + info->adapterName = _adapter ? _adapter->getName() : string(); + info = info->underlying; + } return _info; } diff --git a/cpp/src/Ice/EndpointFactory.h b/cpp/src/Ice/EndpointFactory.h index 09c4912d53e..07b3fbd32f2 100644 --- a/cpp/src/Ice/EndpointFactory.h +++ b/cpp/src/Ice/EndpointFactory.h @@ -39,7 +39,7 @@ public: virtual EndpointIPtr read(Ice::InputStream*) const = 0; virtual void destroy() = 0; - virtual EndpointFactoryPtr clone(const ProtocolInstancePtr&) const = 0; + virtual EndpointFactoryPtr clone(const ProtocolInstancePtr&, const EndpointFactoryPtr&) const = 0; protected: diff --git a/cpp/src/Ice/EndpointI.cpp b/cpp/src/Ice/EndpointI.cpp index 31e98dacbd6..af4a2244602 100644 --- a/cpp/src/Ice/EndpointI.cpp +++ b/cpp/src/Ice/EndpointI.cpp @@ -8,6 +8,7 @@ // ********************************************************************** #include <Ice/EndpointI.h> +#include <Ice/OutputStream.h> using namespace std; @@ -16,6 +17,14 @@ IceUtil::Shared* IceInternal::upCast(EndpointI* p) { return p; } IceUtil::Shared* IceInternal::upCast(EndpointI_connectors* p) { return p; } #endif +void +IceInternal::EndpointI::streamWrite(Ice::OutputStream* s) const +{ + s->startEncapsulation(); + streamWriteImpl(s); + s->endEncapsulation(); +} + string IceInternal::EndpointI::toString() const { diff --git a/cpp/src/Ice/EndpointI.h b/cpp/src/Ice/EndpointI.h index 1f4ae56117e..b2260474d3d 100644 --- a/cpp/src/Ice/EndpointI.h +++ b/cpp/src/Ice/EndpointI.h @@ -46,7 +46,8 @@ public: // // Marshal the endpoint. // - virtual void streamWrite(Ice::OutputStream*) const = 0; + virtual void streamWrite(Ice::OutputStream*) const; + virtual void streamWriteImpl(Ice::OutputStream*) const = 0; // // Return the endpoint type. @@ -177,6 +178,8 @@ public: InfoI(const EndpointIPtr& endpoint) : _endpoint(endpoint) { + T::compress = _endpoint->compress(); + T::timeout = _endpoint->timeout(); } virtual Ice::Short diff --git a/cpp/src/Ice/IPEndpointI.cpp b/cpp/src/Ice/IPEndpointI.cpp index 824864a7588..21f4def1c2d 100644 --- a/cpp/src/Ice/IPEndpointI.cpp +++ b/cpp/src/Ice/IPEndpointI.cpp @@ -106,11 +106,10 @@ IceInternal::IPEndpointI::secure() const } void -IceInternal::IPEndpointI::streamWrite(OutputStream* s) const +IceInternal::IPEndpointI::streamWriteImpl(OutputStream* s) const { - s->startEncapsulation(); - streamWriteImpl(s); - s->endEncapsulation(); + s->write(_host, false); + s->write(_port); } const string& @@ -132,18 +131,6 @@ IceInternal::IPEndpointI::connectionId(const string& connectionId) const } } -const std::string& -IceInternal::IPEndpointI::host() const -{ - return _host; -} - -int -IceInternal::IPEndpointI::port() const -{ - return _port; -} - void IceInternal::IPEndpointI::connectors_async(Ice::EndpointSelectionType selType, const EndpointI_connectorsPtr& cb) const { @@ -355,13 +342,6 @@ IceInternal::IPEndpointI::connectors(const vector<Address>& addresses, const Net } void -IceInternal::IPEndpointI::streamWriteImpl(OutputStream* s) const -{ - s->write(_host, false); - s->write(_port); -} - -void IceInternal::IPEndpointI::hashInit(Ice::Int& h) const { hashAdd(h, _host); diff --git a/cpp/src/Ice/IPEndpointI.h b/cpp/src/Ice/IPEndpointI.h index 3c6e520da2e..a2ed7984037 100644 --- a/cpp/src/Ice/IPEndpointI.h +++ b/cpp/src/Ice/IPEndpointI.h @@ -47,11 +47,12 @@ class ICE_API IPEndpointI : public EndpointI, public Ice::EnableSharedFromThis<I { public: + virtual void streamWriteImpl(Ice::OutputStream*) const; + virtual Ice::EndpointInfoPtr getInfo() const; virtual Ice::Short type() const; virtual const std::string& protocol() const; virtual bool secure() const; - virtual void streamWrite(Ice::OutputStream*) const; virtual const std::string& connectionId() const; virtual EndpointIPtr connectionId(const ::std::string&) const; @@ -71,10 +72,7 @@ public: #endif virtual std::vector<ConnectorPtr> connectors(const std::vector<Address>&, const NetworkProxyPtr&) const; - const std::string& host() const; - int port() const; - virtual void streamWriteImpl(Ice::OutputStream*) const; virtual void hashInit(Ice::Int&) const; virtual void fillEndpointInfo(Ice::IPEndpointInfo*) const; diff --git a/cpp/src/Ice/Incoming.cpp b/cpp/src/Ice/Incoming.cpp index 5e7e0616943..5bd91cb36c3 100644 --- a/cpp/src/Ice/Incoming.cpp +++ b/cpp/src/Ice/Incoming.cpp @@ -183,11 +183,14 @@ IceInternal::IncomingBase::__warning(const Exception& ex) const if(_current.con) { - Ice::ConnectionInfoPtr connInfo = _current.con->getInfo(); - Ice::IPConnectionInfoPtr ipConnInfo = ICE_DYNAMIC_CAST(Ice::IPConnectionInfo, connInfo); - if(ipConnInfo) + for(Ice::ConnectionInfoPtr connInfo = _current.con->getInfo(); connInfo; connInfo = connInfo->underlying) { - out << "\nremote host: " << ipConnInfo->remoteAddress << " remote port: " << ipConnInfo->remotePort; + Ice::IPConnectionInfoPtr ipConnInfo = ICE_DYNAMIC_CAST(Ice::IPConnectionInfo, connInfo); + if(ipConnInfo) + { + out << "\nremote host: " << ipConnInfo->remoteAddress << " remote port: " << ipConnInfo->remotePort; + break; + } } } } @@ -204,11 +207,14 @@ IceInternal::IncomingBase::__warning(const string& msg) const if(_current.con) { - Ice::ConnectionInfoPtr connInfo = _current.con->getInfo(); - Ice::IPConnectionInfoPtr ipConnInfo = ICE_DYNAMIC_CAST(Ice::IPConnectionInfo, connInfo); - if(ipConnInfo) + for(Ice::ConnectionInfoPtr connInfo = _current.con->getInfo(); connInfo; connInfo = connInfo->underlying) { - out << "\nremote host: " << ipConnInfo->remoteAddress << " remote port: " << ipConnInfo->remotePort; + Ice::IPConnectionInfoPtr ipConnInfo = ICE_DYNAMIC_CAST(Ice::IPConnectionInfo, connInfo); + if(ipConnInfo) + { + out << "\nremote host: " << ipConnInfo->remoteAddress << " remote port: " << ipConnInfo->remotePort; + break; + } } } } diff --git a/cpp/src/Ice/Instance.cpp b/cpp/src/Ice/Instance.cpp index a561645ea64..460ec504c4f 100644 --- a/cpp/src/Ice/Instance.cpp +++ b/cpp/src/Ice/Instance.cpp @@ -1115,7 +1115,7 @@ IceInternal::Instance::Instance(const CommunicatorPtr& communicator, const Initi #endif if(!logfile.empty()) { - _initData.logger = ICE_MAKE_SHARED(LoggerI, _initData.properties->getProperty("Ice.ProgramName"), logfile, true, ICE_NULLPTR, + _initData.logger = ICE_MAKE_SHARED(LoggerI, _initData.properties->getProperty("Ice.ProgramName"), logfile, true, ICE_NULLPTR, _initData.properties->getPropertyAsIntWithDefault("Ice.LogFile.SizeMax", 0)); } else @@ -1330,13 +1330,13 @@ IceInternal::Instance::finishSetup(int& argc, char* argv[], const Ice::Communica if(tcpFactory) { ProtocolInstancePtr instance = new ProtocolInstance(communicator, WSEndpointType, "ws", false); - _endpointFactoryManager->add(new WSEndpointFactory(instance, tcpFactory->clone(instance))); + _endpointFactoryManager->add(new WSEndpointFactory(instance, tcpFactory->clone(instance, 0))); } EndpointFactoryPtr sslFactory = _endpointFactoryManager->get(SSLEndpointType); if(sslFactory) { ProtocolInstancePtr instance = new ProtocolInstance(communicator, WSSEndpointType, "wss", true); - _endpointFactoryManager->add(new WSEndpointFactory(instance, sslFactory->clone(instance))); + _endpointFactoryManager->add(new WSEndpointFactory(instance, sslFactory->clone(instance, 0))); } // @@ -1838,9 +1838,9 @@ IceInternal::Instance::addObjectFactory(const Ice::ObjectFactoryPtr& factory, co // #ifdef ICE_CPP11_MAPPING _initData.valueFactoryManager->add([factory](const string& id) - { - return factory->create(id); - }, + { + return factory->create(id); + }, id); #else class ValueFactoryWrapper: public Ice::ValueFactory diff --git a/cpp/src/Ice/InstrumentationI.cpp b/cpp/src/Ice/InstrumentationI.cpp index 6fbedad641f..62f8bda1285 100644 --- a/cpp/src/Ice/InstrumentationI.cpp +++ b/cpp/src/Ice/InstrumentationI.cpp @@ -74,6 +74,20 @@ struct ThreadStateChanged ThreadState newState; }; +IPConnectionInfo* +getIPConnectionInfo(const ConnectionInfoPtr& info) +{ + for(ConnectionInfoPtr p = info; p; p = p->underlying) + { + IPConnectionInfo* ipInfo = dynamic_cast<IPConnectionInfo*>(p.get()); + if(ipInfo) + { + return ipInfo; + } + } + return ICE_NULLPTR; +} + class ConnectionHelper : public MetricsHelperT<ConnectionMetrics> { public: @@ -108,7 +122,7 @@ public: if(_id.empty()) { ostringstream os; - IPConnectionInfoPtr info = ICE_DYNAMIC_CAST(IPConnectionInfo, _connectionInfo); + IPConnectionInfo* info = getIPConnectionInfo(_connectionInfo); if(info) { os << info->localAddress << ':' << info->localPort; diff --git a/cpp/src/Ice/Makefile.mk b/cpp/src/Ice/Makefile.mk index fe90b914e73..44890c32c18 100644 --- a/cpp/src/Ice/Makefile.mk +++ b/cpp/src/Ice/Makefile.mk @@ -26,8 +26,6 @@ Ice_excludes += src/IceUtil/ConvertUTF.cpp src/IceUtil/Unicode.cpp endif Ice[iphoneos]_extra_sources := $(wildcard $(addprefix $(currentdir)/ios/,*.cpp *.mm)) -Ice[iphoneos]_excludes := $(currentdir)/RegisterPluginsInit.cpp Ice[iphonesimulator]_extra_sources = $(Ice[iphoneos]_extra_sources) -Ice[iphonesimulator]_excludes = $(Ice[iphoneos]_excludes) projects += $(project) diff --git a/cpp/src/Ice/Network.cpp b/cpp/src/Ice/Network.cpp index d1da40b9b51..317e1e3bbc4 100644..100755 --- a/cpp/src/Ice/Network.cpp +++ b/cpp/src/Ice/Network.cpp @@ -812,12 +812,112 @@ IceInternal::NativeInfo::completed(SocketOperation operation) #elif defined(ICE_OS_WINRT) void +IceInternal::NativeInfo::queueAction(SocketOperation op, IAsyncAction^ action, bool connect) +{ + AsyncInfo* asyncInfo = getAsyncInfo(op); + if(checkIfErrorOrCompleted(op, action, connect)) + { + asyncInfo->count = 0; + } + else + { + action->Completed = ref new AsyncActionCompletedHandler( + [=] (IAsyncAction^ info, Windows::Foundation::AsyncStatus status) + { + if(status != Windows::Foundation::AsyncStatus::Completed) + { + asyncInfo->count = SOCKET_ERROR; + asyncInfo->error = info->ErrorCode.Value; + } + else + { + asyncInfo->count = 0; + } + completed(op); + }); + } +} + +void +IceInternal::NativeInfo::queueOperation(SocketOperation op, IAsyncOperation<unsigned int>^ operation) +{ + AsyncInfo* info = getAsyncInfo(op); + if(checkIfErrorOrCompleted(op, operation)) + { + info->count = static_cast<int>(operation->GetResults()); + } + else + { + if(!info->completedHandler) + { + info->completedHandler = ref new AsyncOperationCompletedHandler<unsigned int>( + [=] (IAsyncOperation<unsigned int>^ operation, Windows::Foundation::AsyncStatus status) + { + if(status != Windows::Foundation::AsyncStatus::Completed) + { + info->count = SOCKET_ERROR; + info->error = operation->ErrorCode.Value; + } + else + { + info->count = static_cast<int>(operation->GetResults()); + } + completed(op); + }); + } + operation->Completed = info->completedHandler; + } +} + +void +IceInternal::NativeInfo::setCompletedHandler(SocketOperationCompletedHandler^ handler) +{ + _completedHandler = handler; +} + +void IceInternal::NativeInfo::completed(SocketOperation operation) { assert(_completedHandler); _completedHandler(operation); } +bool +IceInternal::NativeInfo::checkIfErrorOrCompleted(SocketOperation op, IAsyncInfo^ info, bool connect) +{ + // + // NOTE: It's important to only check for info->Status once as it + // might change during the checks below (the Status can be changed + // by the Windows thread pool concurrently). + // + // We consider that a canceled async status is the same as an + // error. A canceled async status can occur if there's a timeout + // and the socket is closed. + // + Windows::Foundation::AsyncStatus status = info->Status; + if(status == Windows::Foundation::AsyncStatus::Completed) + { + _completedHandler(op); + return true; + } + else if (status == Windows::Foundation::AsyncStatus::Started) + { + return false; + } + else + { + if(connect) // Connect + { + checkConnectErrorCode(__FILE__, __LINE__, info->ErrorCode.Value); + } + else + { + checkErrorCode(__FILE__, __LINE__, info->ErrorCode.Value); + } + return true; // Prevent compiler warning. + } +} + #endif bool @@ -1996,6 +2096,9 @@ IceInternal::setReuseAddress(SOCKET fd, bool reuse) #ifdef ICE_OS_WINRT +namespace +{ + void checkResultAndWait(IAsyncAction^ action) { @@ -2023,6 +2126,8 @@ checkResultAndWait(IAsyncAction^ action) checkErrorCode(__FILE__, __LINE__, action->ErrorCode.Value); } } + +} #endif Address @@ -2561,7 +2666,7 @@ IceInternal::createPipe(SOCKET fds[2]) #else // ICE_OS_WINRT void -IceInternal::checkConnectErrorCode(const char* file, int line, HRESULT herr, HostName^ host) +IceInternal::checkConnectErrorCode(const char* file, int line, HRESULT herr) { if(herr == E_ACCESSDENIED) { @@ -2591,11 +2696,6 @@ IceInternal::checkConnectErrorCode(const char* file, int line, HRESULT herr, Hos { DNSException ex(file, line); ex.error = static_cast<int>(error); - // - // Don't need to pass a wide string converter as the wide string come from - // Windows API. - // - ex.host = IceUtil::wstringToString(host->RawName->Data(), IceUtil::getProcessStringConverter()); throw ex; } else diff --git a/cpp/src/Ice/Network.h b/cpp/src/Ice/Network.h index 5d40847bdde..aae80089dbe 100644..100755 --- a/cpp/src/Ice/Network.h +++ b/cpp/src/Ice/Network.h @@ -179,6 +179,7 @@ struct ICE_API AsyncInfo : WSAOVERLAPPED #elif defined(ICE_OS_WINRT) struct ICE_API AsyncInfo { + Windows::Foundation::AsyncOperationCompletedHandler<unsigned int>^ completedHandler; int count; int error; }; @@ -221,10 +222,13 @@ public: #if defined(ICE_USE_IOCP) virtual AsyncInfo* getAsyncInfo(SocketOperation) = 0; void initialize(HANDLE, ULONG_PTR); - void completed(SocketOperation operation); + void completed(SocketOperation); #elif defined(ICE_OS_WINRT) - virtual void setCompletedHandler(SocketOperationCompletedHandler^) = 0; - void completed(SocketOperation operation); + virtual AsyncInfo* getAsyncInfo(SocketOperation) = 0; + void queueAction(SocketOperation, Windows::Foundation::IAsyncAction^, bool = false); + void queueOperation(SocketOperation, Windows::Foundation::IAsyncOperation<unsigned int>^); + void setCompletedHandler(SocketOperationCompletedHandler^); + void completed(SocketOperation); #endif protected: @@ -236,6 +240,7 @@ protected: HANDLE _handle; ULONG_PTR _key; #elif defined(ICE_OS_WINRT) + bool checkIfErrorOrCompleted(SocketOperation, Windows::Foundation::IAsyncInfo^, bool = false); SocketOperationCompletedHandler^ _completedHandler; #endif }; @@ -287,6 +292,7 @@ ICE_API void setMcastTtl(SOCKET, int, const Address&); ICE_API void setReuseAddress(SOCKET, bool); ICE_API Address doBind(SOCKET, const Address&); +ICE_API void doListen(SOCKET, int); #ifndef ICE_OS_WINRT ICE_API bool interrupted(); @@ -301,7 +307,6 @@ ICE_API bool connectionRefused(); ICE_API bool connectInProgress(); ICE_API bool connectionLost(); -ICE_API void doListen(SOCKET, int); ICE_API bool doConnect(SOCKET, const Address&, const Address&); ICE_API void doFinishConnect(SOCKET); ICE_API SOCKET doAccept(SOCKET); @@ -312,7 +317,7 @@ ICE_API int getSocketErrno(); ICE_API Address getNumericAddress(const std::string&); #else -ICE_API void checkConnectErrorCode(const char*, int, HRESULT, Windows::Networking::HostName^); +ICE_API void checkConnectErrorCode(const char*, int, HRESULT); ICE_API void checkErrorCode(const char*, int, HRESULT); #endif diff --git a/cpp/src/Ice/OpaqueEndpointI.cpp b/cpp/src/Ice/OpaqueEndpointI.cpp index 838fcc6252f..d6c8bdbf984 100644 --- a/cpp/src/Ice/OpaqueEndpointI.cpp +++ b/cpp/src/Ice/OpaqueEndpointI.cpp @@ -92,7 +92,7 @@ private: // OpaqueEndpointInfoI::OpaqueEndpointInfoI(Ice::Short type, const Ice::EncodingVersion& rawEncoding, const Ice::ByteSeq& rawBytes) : - Ice::OpaqueEndpointInfo(-1, false, rawEncoding, rawBytes), + Ice::OpaqueEndpointInfo(ICE_NULLPTR, -1, false, rawEncoding, rawBytes), _type(type) { } @@ -320,6 +320,12 @@ IceInternal::OpaqueEndpointI::operator<(const LocalObject& r) const return false; } +void +IceInternal::OpaqueEndpointI::streamWriteImpl(Ice::OutputStream*) const +{ + assert(false); +} + bool IceInternal::OpaqueEndpointI::checkOption(const string& option, const string& argument, const string& endpoint) { diff --git a/cpp/src/Ice/OpaqueEndpointI.h b/cpp/src/Ice/OpaqueEndpointI.h index fa4add29b16..a0ebae3a49f 100644 --- a/cpp/src/Ice/OpaqueEndpointI.h +++ b/cpp/src/Ice/OpaqueEndpointI.h @@ -57,6 +57,7 @@ public: protected: + virtual void streamWriteImpl(Ice::OutputStream*) const; virtual bool checkOption(const std::string&, const std::string&, const std::string&); private: diff --git a/cpp/src/Ice/Selector.cpp b/cpp/src/Ice/Selector.cpp index 580d51d74fe..ade367f2a40 100644 --- a/cpp/src/Ice/Selector.cpp +++ b/cpp/src/Ice/Selector.cpp @@ -22,12 +22,10 @@ using namespace std; using namespace IceInternal; -#ifdef ICE_OS_WINRT -//using namespace Windows::Foundation; +#if defined(ICE_OS_WINRT) using namespace Windows::Storage::Streams; using namespace Windows::Networking; using namespace Windows::Networking::Sockets; - #endif #if defined(ICE_USE_IOCP) || defined(ICE_OS_WINRT) diff --git a/cpp/src/Ice/StreamSocket.cpp b/cpp/src/Ice/StreamSocket.cpp index fa3761f5fa0..7d186e15dd4 100644..100755 --- a/cpp/src/Ice/StreamSocket.cpp +++ b/cpp/src/Ice/StreamSocket.cpp @@ -13,6 +13,14 @@ using namespace IceInternal; +#if defined(ICE_OS_WINRT) + +#include <Ice/Properties.h> +using namespace Platform; +using namespace Windows::Foundation; + +#endif + StreamSocket::StreamSocket(const ProtocolInstancePtr& instance, const NetworkProxyPtr& proxy, const Address& addr, @@ -23,13 +31,12 @@ StreamSocket::StreamSocket(const ProtocolInstancePtr& instance, _addr(addr), _sourceAddr(sourceAddr), _state(StateNeedConnect) -#ifdef ICE_USE_IOCP - , _read(SocketOperationRead), - _write(SocketOperationWrite) +#if defined(ICE_USE_IOCP) + , _read(SocketOperationRead), _write(SocketOperationWrite) #endif { init(); -#ifndef ICE_USE_IOCP +#if !defined(ICE_USE_IOCP) && !defined(ICE_OS_WINRT) if(doConnect(_fd, _proxy ? _proxy->getAddress() : _addr, sourceAddr)) { _state = _proxy ? StateProxyWrite : StateConnected; @@ -49,10 +56,11 @@ StreamSocket::StreamSocket(const ProtocolInstancePtr& instance, StreamSocket::StreamSocket(const ProtocolInstancePtr& instance, SOCKET fd) : NativeInfo(fd), _instance(instance), - _state(StateConnected) -#ifdef ICE_USE_IOCP - , _read(SocketOperationRead), - _write(SocketOperationWrite) + _addr(), + _sourceAddr(), + _state(StateConnected) +#if defined(ICE_USE_IOCP) + , _read(SocketOperationRead), _write(SocketOperationWrite) #endif { init(); @@ -82,8 +90,26 @@ StreamSocket::connect(Buffer& readBuffer, Buffer& writeBuffer) } else if(_state <= StateConnectPending) { -#ifdef ICE_USE_IOCP +#if defined(ICE_USE_IOCP) doFinishConnectAsync(_fd, _write); +#elif defined(ICE_OS_WINRT) + if(_write.count == SOCKET_ERROR) + { + try + { + checkConnectErrorCode(__FILE__, __LINE__, _write.error); + } + catch(Ice::DNSException& ex) + { + // + // Don't need to pass a wide string converter as the wide string come from + // Windows API. + // + const Address& addr = _proxy ? _proxy->getAddress() : _addr; + ex.host = IceUtil::wstringToString(addr.host->RawName->Data(), IceUtil::getProcessStringConverter()); + throw; + } + } #else doFinishConnect(_fd); #endif @@ -127,7 +153,7 @@ StreamSocket::isConnected() size_t StreamSocket::getSendPacketSize(size_t length) { -#ifdef ICE_USE_IOCP +#if defined(ICE_USE_IOCP) || defined(ICE_OS_WINRT) return _maxSendPacketSize > 0 ? std::min(length, _maxSendPacketSize) : length; #else return length; @@ -137,7 +163,7 @@ StreamSocket::getSendPacketSize(size_t length) size_t StreamSocket::getRecvPacketSize(size_t length) { -#ifdef ICE_USE_IOCP +#if defined(ICE_USE_IOCP) || defined(ICE_OS_WINRT) return _maxRecvPacketSize > 0 ? std::min(length, _maxRecvPacketSize) : length; #else return length; @@ -153,6 +179,7 @@ StreamSocket::setBufferSize(int rcvSize, int sndSize) SocketOperation StreamSocket::read(Buffer& buf) { +#if !defined(ICE_OS_WINRT) if(_state == StateProxyRead) { while(true) @@ -171,12 +198,14 @@ StreamSocket::read(Buffer& buf) } } buf.i += read(reinterpret_cast<char*>(&*buf.i), buf.b.end() - buf.i); +#endif return buf.i != buf.b.end() ? SocketOperationRead : SocketOperationNone; } SocketOperation StreamSocket::write(Buffer& buf) { +#if !defined(ICE_OS_WINRT) if(_state == StateProxyWrite) { while(true) @@ -195,9 +224,11 @@ StreamSocket::write(Buffer& buf) } } buf.i += write(reinterpret_cast<const char*>(&*buf.i), buf.b.end() - buf.i); +#endif return buf.i != buf.b.end() ? SocketOperationWrite : SocketOperationNone; } +#if !defined(ICE_OS_WINRT) ssize_t StreamSocket::read(char* buf, size_t length) { @@ -278,7 +309,6 @@ StreamSocket::write(const char* buf, size_t length) #else size_t packetSize = length; #endif - ssize_t sent = 0; while(length > 0) { @@ -336,8 +366,9 @@ StreamSocket::write(const char* buf, size_t length) } return sent; } +#endif -#ifdef ICE_USE_IOCP +#if defined(ICE_USE_IOCP) || defined(ICE_OS_WINRT) AsyncInfo* StreamSocket::getAsyncInfo(SocketOperation op) { @@ -352,6 +383,9 @@ StreamSocket::getAsyncInfo(SocketOperation op) return 0; } } +#endif + +#if defined(ICE_USE_IOCP) bool StreamSocket::startWrite(Buffer& buf) @@ -489,7 +523,132 @@ StreamSocket::finishRead(Buffer& buf) { _state = toState(_proxy->endRead(buf)); } + +} + +#elif defined(ICE_OS_WINRT) + +bool +StreamSocket::startWrite(Buffer& buf) +{ + if(_state == StateConnectPending) + { + const Address& addr = _proxy ? _proxy->getAddress() : _addr; + try + { + try + { + queueAction(SocketOperationConnect, + safe_cast<Windows::Networking::Sockets::StreamSocket^>(_fd)->ConnectAsync(addr.host, addr.port, + Windows::Networking::Sockets::SocketProtectionLevel::PlainSocket), true); + } + catch(Platform::Exception^ ex) + { + checkConnectErrorCode(__FILE__, __LINE__, ex->HResult); + } + } + catch(Ice::DNSException& ex) + { + // + // Don't need to pass a wide string converter as the wide string come from + // Windows API. + // + ex.host = IceUtil::wstringToString(addr.host->RawName->Data(), IceUtil::getProcessStringConverter()); + throw; + } + return false; + } + + assert(!buf.b.empty()); + assert(buf.i != buf.b.end()); + + size_t packetSize = static_cast<size_t>(buf.b.end() - buf.i); + if(_maxSendPacketSize > 0 && packetSize > _maxSendPacketSize) + { + packetSize = _maxSendPacketSize; + } + assert(packetSize > 0); + _writer->WriteBytes(ref new Array<unsigned char>(&*buf.i, packetSize)); + try + { + queueOperation(SocketOperationWrite, _writer->StoreAsync()); + } + catch(Platform::Exception^ ex) + { + checkErrorCode(__FILE__, __LINE__, ex->HResult); + } + return packetSize == static_cast<int>(buf.b.end() - buf.i); } + +void +StreamSocket::finishWrite(Buffer& buf) +{ + if(_fd == INVALID_SOCKET || (_state < StateConnected && _state != StateProxyWrite)) + { + return; + } + + if(_write.count == SOCKET_ERROR) + { + checkErrorCode(__FILE__, __LINE__, _write.error); + } + + buf.i += _write.count; +} + +void +StreamSocket::startRead(Buffer& buf) +{ + size_t packetSize = static_cast<size_t>(buf.b.end() - buf.i); + if(_maxRecvPacketSize > 0 && packetSize > _maxRecvPacketSize) + { + packetSize = _maxRecvPacketSize; + } + assert(!buf.b.empty() && buf.i != buf.b.end()); + + try + { + queueOperation(SocketOperationRead, _reader->LoadAsync(packetSize)); + } + catch(Platform::Exception^ ex) + { + checkErrorCode(__FILE__, __LINE__, ex->HResult); + } +} + +void +StreamSocket::finishRead(Buffer& buf) +{ + if(_fd == INVALID_SOCKET) + { + return; + } + + if(_read.count == SOCKET_ERROR) + { + checkErrorCode(__FILE__, __LINE__, _read.error); + } + else if(_read.count == 0) + { + Ice::ConnectionLostException ex(__FILE__, __LINE__); + ex.error = 0; + throw ex; + } + + try + { + auto data = ref new Platform::Array<unsigned char>(_read.count); + _reader->ReadBytes(data); + memcpy(&*buf.i, data->Data, _read.count); + } + catch(Platform::Exception^ ex) + { + checkErrorCode(__FILE__, __LINE__, ex->HResult); + } + + buf.i += _read.count; +} + #endif void @@ -520,7 +679,7 @@ StreamSocket::init() setBlock(_fd, false); setTcpBufSize(_fd, _instance); -#ifdef ICE_USE_IOCP +#if defined(ICE_USE_IOCP) // // For timeouts to work properly, we need to receive or send the // data in several chunks when using IOCP WSARecv or WSASend. @@ -530,6 +689,14 @@ StreamSocket::init() // _maxSendPacketSize = std::max(512, IceInternal::getSendBufferSize(_fd)); _maxRecvPacketSize = std::max(512, IceInternal::getRecvBufferSize(_fd)); +#elif defined(ICE_OS_WINRT) + Windows::Networking::Sockets::StreamSocket^ s = safe_cast<Windows::Networking::Sockets::StreamSocket^>(_fd); + _writer = ref new Windows::Storage::Streams::DataWriter(s->OutputStream); + _reader = ref new Windows::Storage::Streams::DataReader(s->InputStream); + _reader->InputStreamOptions = Windows::Storage::Streams::InputStreamOptions::Partial; + + _maxSendPacketSize = std::max(static_cast<unsigned int>(512), s->Control->OutboundBufferSizeInBytes / 2); + _maxRecvPacketSize = _instance->properties()->getPropertyAsIntWithDefault("Ice.TCP.RcvSize", 128 * 1024); #endif } @@ -546,5 +713,3 @@ StreamSocket::toState(SocketOperation operation) const return StateProxyConnected; } } - - diff --git a/cpp/src/Ice/StreamSocket.h b/cpp/src/Ice/StreamSocket.h index ad69b096199..3d092d20ba2 100644 --- a/cpp/src/Ice/StreamSocket.h +++ b/cpp/src/Ice/StreamSocket.h @@ -36,11 +36,16 @@ public: SocketOperation read(Buffer&); SocketOperation write(Buffer&); +#if !defined(ICE_OS_WINRT) ssize_t read(char*, size_t); ssize_t write(const char*, size_t); +#endif -#ifdef ICE_USE_IOCP +#if defined(ICE_USE_IOCP) || defined(ICE_OS_WINRT) AsyncInfo* getAsyncInfo(SocketOperation); +#endif + +#if defined(ICE_USE_IOCP) || defined(ICE_OS_WINRT) bool startWrite(Buffer&); void finishWrite(Buffer&); void startRead(Buffer&); @@ -73,12 +78,17 @@ private: State _state; std::string _desc; -#ifdef ICE_USE_IOCP +#if defined(ICE_USE_IOCP) || defined(ICE_OS_WINRT) size_t _maxSendPacketSize; size_t _maxRecvPacketSize; AsyncInfo _read; AsyncInfo _write; #endif + +#if defined(ICE_OS_WINRT) + Windows::Storage::Streams::DataReader^ _reader; + Windows::Storage::Streams::DataWriter^ _writer; +#endif }; typedef IceUtil::Handle<StreamSocket> StreamSocketPtr; diff --git a/cpp/src/Ice/TcpAcceptor.cpp b/cpp/src/Ice/TcpAcceptor.cpp index 8ca874cc218..e20ad639d91 100644..100755 --- a/cpp/src/Ice/TcpAcceptor.cpp +++ b/cpp/src/Ice/TcpAcceptor.cpp @@ -17,8 +17,21 @@ #include <Ice/StreamSocket.h> #include <IceUtil/StringUtil.h> -#ifdef ICE_USE_IOCP +#if defined(ICE_USE_IOCP) # include <Mswsock.h> +#elif defined(ICE_OS_WINRT) +using namespace Platform; +using namespace Windows::Foundation; +using namespace Windows::Storage::Streams; +using namespace Windows::Networking; +using namespace Windows::Networking::Sockets; +#endif + +// +// Use the system default for the listen() backlog or 511 if not defined. +// +#ifndef SOMAXCONN +# define SOMAXCONN 511 #endif using namespace std; @@ -33,22 +46,28 @@ IceInternal::TcpAcceptor::getNativeInfo() return this; } -#ifdef ICE_USE_IOCP -AsyncInfo* -# ifndef NDEBUG -IceInternal::TcpAcceptor::getAsyncInfo(SocketOperation op) -# else -IceInternal::TcpAcceptor::getAsyncInfo(SocketOperation) -# endif -{ - assert(op == SocketOperationRead); - return &_info; -} -#endif - void IceInternal::TcpAcceptor::close() { +#if defined(ICE_OS_WINRT) + IceUtil::Mutex::Lock lock(_mutex); + if(_acceptPending) + { + assert(_accepted.empty()); + completed(SocketOperationRead); + _acceptPending = false; + } + else if(!_accepted.empty()) + { + for(deque<Windows::Networking::Sockets::StreamSocket^>::const_iterator p = _accepted.begin(); + p != _accepted.end(); ++p) + { + closeSocket(*p); + } + _accepted.clear(); + } +#endif + if(_fd != INVALID_SOCKET) { closeSocketNoThrow(_fd); @@ -62,7 +81,9 @@ IceInternal::TcpAcceptor::listen() try { const_cast<Address&>(_addr) = doBind(_fd, _addr); +#if !defined(ICE_OS_WINRT) doListen(_fd, _backlog); +#endif } catch(...) { @@ -73,7 +94,14 @@ IceInternal::TcpAcceptor::listen() return _endpoint; } -#ifdef ICE_USE_IOCP +#if defined(ICE_USE_IOCP) + +AsyncInfo* +IceInternal::TcpAcceptor::getAsyncInfo(SocketOperation) +{ + return &_info; +} + void IceInternal::TcpAcceptor::startAccept() { @@ -120,12 +148,9 @@ IceInternal::TcpAcceptor::finishAccept() } } -#endif - TransceiverPtr IceInternal::TcpAcceptor::accept() { -#ifdef ICE_USE_IOCP if(_acceptFd == INVALID_SOCKET) { SocketException ex(__FILE__, __LINE__); @@ -144,13 +169,82 @@ IceInternal::TcpAcceptor::accept() SOCKET fd = _acceptFd; _acceptFd = INVALID_SOCKET; + return new TcpTransceiver(_instance, new StreamSocket(_instance, fd)); +} + +#elif defined(ICE_OS_WINRT) + +AsyncInfo* +IceInternal::TcpAcceptor::getAsyncInfo(SocketOperation) +{ + return 0; // Not used +} + +void +IceInternal::TcpAcceptor::startAccept() +{ + assert(_fd != INVALID_SOCKET); + + // + // If there are already sockets waiting to be accepted, we just + // notify the selector that the acceptor is ready for acceting the + // new socket. Otherwise, we set the _acceptPending flag, when a + // new socket connection event is received, the message handler + // will notify the selector. + // + IceUtil::Mutex::Lock lock(_mutex); + assert(!_acceptPending); + if(!_accepted.empty()) + { + completed(SocketOperationRead); + } + else + { + _acceptPending = true; + } +} + +void +IceInternal::TcpAcceptor::finishAccept() +{ + // + // Nothing to do, we just check there's at least one accepted + // socket or the acceptor was closed. + // + IceUtil::Mutex::Lock lock(_mutex); + assert(!_acceptPending && (!_accepted.empty() || _fd == INVALID_SOCKET)); +} + +TransceiverPtr +IceInternal::TcpAcceptor::accept() +{ + if(_fd == INVALID_SOCKET) // Acceptor closed. + { + assert(_accepted.empty()); + throw SocketException(__FILE__, __LINE__); + } + + Windows::Networking::Sockets::StreamSocket^ fd; + { + IceUtil::Mutex::Lock lock(_mutex); + assert(!_accepted.empty()); + fd = _accepted.front(); + _accepted.pop_front(); + } + + return new TcpTransceiver(_instance, new StreamSocket(_instance, fd)); +} + #else - SOCKET fd = doAccept(_fd); -#endif - return new TcpTransceiver(_instance, new StreamSocket(_instance, fd)); +TransceiverPtr +IceInternal::TcpAcceptor::accept() +{ + return new TcpTransceiver(_instance, new StreamSocket(_instance, doAccept(_fd))); } +#endif + string IceInternal::TcpAcceptor::protocol() const { @@ -191,23 +285,49 @@ IceInternal::TcpAcceptor::TcpAcceptor(const TcpEndpointIPtr& endpoint, _instance(instance), _addr(getAddressForServer(host, port, _instance->protocolSupport(), instance->preferIPv6())) #ifdef ICE_USE_IOCP - , _acceptFd(INVALID_SOCKET), - _info(SocketOperationRead) + , _acceptFd(INVALID_SOCKET), _info(SocketOperationRead) #endif { -#ifdef SOMAXCONN _backlog = instance->properties()->getPropertyAsIntWithDefault("Ice.TCP.Backlog", SOMAXCONN); + +#if defined(ICE_OS_WINRT) + _fd = ref new StreamSocketListener(); + safe_cast<StreamSocketListener^>(_fd)->ConnectionReceived += + ref new TypedEventHandler<StreamSocketListener^, StreamSocketListenerConnectionReceivedEventArgs^>( + [=](StreamSocketListener^, StreamSocketListenerConnectionReceivedEventArgs^ args) + { + IceUtil::Mutex::Lock lock(_mutex); + if(_fd == INVALID_SOCKET) // Acceptor was closed. + { + closeSocket(args->Socket); + return; + } + _accepted.push_back(args->Socket); + + // + // If the acceptor is waiting for a socket to be accepted, notify + // the selector that the acceptor is ready for "read". This will + // in turn caused finishAccept() and accept() to be called by the + // thread pool. If the acceptor isn't ready to accept the socket, + // it is just queued, when startAccept is called it will be dequed. + // + if(_acceptPending) + { + completed(SocketOperationRead); + _acceptPending = false; + } + }); #else - _backlog = instance->properties()->getPropertyAsIntWithDefault("Ice.TCP.Backlog", 511); + _fd = createServerSocket(false, _addr, instance->protocolSupport()); #endif - _fd = createServerSocket(false, _addr, instance->protocolSupport()); #ifdef ICE_USE_IOCP _acceptBuf.resize((sizeof(sockaddr_storage) + 16) * 2); #endif setBlock(_fd, false); setTcpBufSize(_fd, _instance); + #ifndef _WIN32 // // Enable SO_REUSEADDR on Unix platforms to allow re-using the diff --git a/cpp/src/Ice/TcpAcceptor.h b/cpp/src/Ice/TcpAcceptor.h index c5e23428895..2d9fc24d72f 100644 --- a/cpp/src/Ice/TcpAcceptor.h +++ b/cpp/src/Ice/TcpAcceptor.h @@ -15,6 +15,10 @@ #include <Ice/Acceptor.h> #include <Ice/Network.h> +#if defined(ICE_OS_WINRT) +#include <deque> +#endif + namespace IceInternal { @@ -25,13 +29,13 @@ class TcpAcceptor : public Acceptor, public NativeInfo public: virtual NativeInfoPtr getNativeInfo(); -#ifdef ICE_USE_IOCP +#if defined(ICE_USE_IOCP) || defined(ICE_OS_WINRT) virtual AsyncInfo* getAsyncInfo(SocketOperation); #endif virtual void close(); virtual EndpointIPtr listen(); -#ifdef ICE_USE_IOCP +#if defined(ICE_USE_IOCP) || defined(ICE_OS_WINRT) virtual void startAccept(); virtual void finishAccept(); #endif @@ -54,11 +58,15 @@ private: const Address _addr; int _backlog; -#ifdef ICE_USE_IOCP +#if defined(ICE_USE_IOCP) SOCKET _acceptFd; int _acceptError; std::vector<char> _acceptBuf; AsyncInfo _info; +#elif defined(ICE_OS_WINRT) + IceUtil::Mutex _mutex; + bool _acceptPending; + std::deque<Windows::Networking::Sockets::StreamSocket^> _accepted; #endif }; diff --git a/cpp/src/Ice/TcpEndpointI.cpp b/cpp/src/Ice/TcpEndpointI.cpp index 1caadefbae2..2b2e26e924e 100644 --- a/cpp/src/Ice/TcpEndpointI.cpp +++ b/cpp/src/Ice/TcpEndpointI.cpp @@ -62,21 +62,19 @@ IceInternal::TcpEndpointI::TcpEndpointI(const ProtocolInstancePtr& instance, Inp s->read(const_cast<bool&>(_compress)); } -EndpointInfoPtr -IceInternal::TcpEndpointI::getInfo() const +void +IceInternal::TcpEndpointI::streamWriteImpl(OutputStream* s) const { - TCPEndpointInfoPtr info = ICE_MAKE_SHARED(InfoI<Ice::TCPEndpointInfo>, - ICE_DYNAMIC_CAST(TcpEndpointI, shared_from_this())); - fillEndpointInfo(info.get()); - return info; + IPEndpointI::streamWriteImpl(s); + s->write(_timeout); + s->write(_compress); } EndpointInfoPtr -IceInternal::TcpEndpointI::getWSInfo(const string& resource) const +IceInternal::TcpEndpointI::getInfo() const { - WSEndpointInfoPtr info = ICE_MAKE_SHARED(InfoI<Ice::WSEndpointInfo>, shared_from_this()); + TCPEndpointInfoPtr info = ICE_MAKE_SHARED(InfoI<Ice::TCPEndpointInfo>, shared_from_this()); fillEndpointInfo(info.get()); - info->resource = resource; return info; } @@ -254,14 +252,6 @@ IceInternal::TcpEndpointI::operator<(const LocalObject& r) const } void -IceInternal::TcpEndpointI::streamWriteImpl(OutputStream* s) const -{ - IPEndpointI::streamWriteImpl(s); - s->write(_timeout); - s->write(_compress); -} - -void IceInternal::TcpEndpointI::hashInit(Ice::Int& h) const { IPEndpointI::hashInit(h); @@ -385,7 +375,7 @@ IceInternal::TcpEndpointFactory::destroy() } EndpointFactoryPtr -IceInternal::TcpEndpointFactory::clone(const ProtocolInstancePtr& instance) const +IceInternal::TcpEndpointFactory::clone(const ProtocolInstancePtr& instance, const EndpointFactoryPtr&) const { return new TcpEndpointFactory(instance); } diff --git a/cpp/src/Ice/TcpEndpointI.h b/cpp/src/Ice/TcpEndpointI.h index ffc6743e213..f40c5c14713 100644 --- a/cpp/src/Ice/TcpEndpointI.h +++ b/cpp/src/Ice/TcpEndpointI.h @@ -14,12 +14,11 @@ #include <Ice/IPEndpointI.h> #include <Ice/EndpointFactory.h> #include <Ice/Network.h> // for IceIternal::Address -#include <Ice/WSEndpoint.h> namespace IceInternal { -class TcpEndpointI : public IPEndpointI, public WSEndpointDelegate +class TcpEndpointI : public IPEndpointI, public Ice::EnableSharedFromThis<TcpEndpointI> { public: @@ -28,8 +27,9 @@ public: TcpEndpointI(const ProtocolInstancePtr&); TcpEndpointI(const ProtocolInstancePtr&, Ice::InputStream*); + virtual void streamWriteImpl(Ice::OutputStream*) const; + virtual Ice::EndpointInfoPtr getInfo() const; - virtual Ice::EndpointInfoPtr getWSInfo(const std::string&) const; virtual Ice::Int timeout() const; virtual EndpointIPtr timeout(Ice::Int) const; @@ -51,10 +51,10 @@ public: TcpEndpointIPtr endpoint(const TcpAcceptorPtr&) const; using IPEndpointI::connectionId; + using Ice::EnableSharedFromThis<TcpEndpointI>::shared_from_this; protected: - virtual void streamWriteImpl(Ice::OutputStream*) const; virtual void hashInit(Ice::Int&) const; virtual void fillEndpointInfo(Ice::IPEndpointInfo*) const; virtual bool checkOption(const std::string&, const std::string&, const std::string&); @@ -84,7 +84,7 @@ public: virtual EndpointIPtr read(Ice::InputStream*) const; virtual void destroy(); - virtual EndpointFactoryPtr clone(const ProtocolInstancePtr&) const; + virtual EndpointFactoryPtr clone(const ProtocolInstancePtr&, const EndpointFactoryPtr&) const; private: diff --git a/cpp/src/Ice/TcpTransceiver.cpp b/cpp/src/Ice/TcpTransceiver.cpp index 99898f4e2be..be280be0476 100644 --- a/cpp/src/Ice/TcpTransceiver.cpp +++ b/cpp/src/Ice/TcpTransceiver.cpp @@ -60,7 +60,7 @@ IceInternal::TcpTransceiver::read(Buffer& buf) return _stream->read(buf); } -#ifdef ICE_USE_IOCP +#if defined(ICE_USE_IOCP) || defined(ICE_OS_WINRT) bool IceInternal::TcpTransceiver::startWrite(Buffer& buf) { @@ -108,16 +108,12 @@ Ice::ConnectionInfoPtr IceInternal::TcpTransceiver::getInfo() const { TCPConnectionInfoPtr info = ICE_MAKE_SHARED(TCPConnectionInfo); - fillConnectionInfo(info); - return info; -} - -Ice::ConnectionInfoPtr -IceInternal::TcpTransceiver::getWSInfo(const Ice::HeaderDict& headers) const -{ - WSConnectionInfoPtr info = ICE_MAKE_SHARED(WSConnectionInfo); - fillConnectionInfo(info); - info->headers = headers; + fdToAddressAndPort(_stream->fd(), info->localAddress, info->localPort, info->remoteAddress, info->remotePort); + if(_stream->fd() != INVALID_SOCKET) + { + info->rcvSize = getRecvBufferSize(_stream->fd()); + info->sndSize = getSendBufferSize(_stream->fd()); + } return info; } @@ -141,14 +137,3 @@ IceInternal::TcpTransceiver::TcpTransceiver(const ProtocolInstancePtr& instance, IceInternal::TcpTransceiver::~TcpTransceiver() { } - -void -IceInternal::TcpTransceiver::fillConnectionInfo(const TCPConnectionInfoPtr& info) const -{ - fdToAddressAndPort(_stream->fd(), info->localAddress, info->localPort, info->remoteAddress, info->remotePort); - if(_stream->fd() != INVALID_SOCKET) - { - info->rcvSize = getRecvBufferSize(_stream->fd()); - info->sndSize = getSendBufferSize(_stream->fd()); - } -} diff --git a/cpp/src/Ice/TcpTransceiver.h b/cpp/src/Ice/TcpTransceiver.h index f2890ba076c..198b4aeab77 100644 --- a/cpp/src/Ice/TcpTransceiver.h +++ b/cpp/src/Ice/TcpTransceiver.h @@ -14,7 +14,6 @@ #include <Ice/Transceiver.h> #include <Ice/Network.h> #include <Ice/StreamSocket.h> -#include <Ice/WSTransceiver.h> namespace IceInternal { @@ -22,7 +21,7 @@ namespace IceInternal class TcpConnector; class TcpAcceptor; -class TcpTransceiver : public Transceiver, public WSTransceiverDelegate +class TcpTransceiver : public Transceiver { public: @@ -37,7 +36,7 @@ public: virtual void close(); virtual SocketOperation write(Buffer&); virtual SocketOperation read(Buffer&); -#ifdef ICE_USE_IOCP +#if defined(ICE_USE_IOCP) || defined(ICE_OS_WINRT) virtual bool startWrite(Buffer&); virtual void finishWrite(Buffer&); virtual void startRead(Buffer&); @@ -47,7 +46,6 @@ public: virtual std::string toString() const; virtual std::string toDetailedString() const; virtual Ice::ConnectionInfoPtr getInfo() const; - virtual Ice::ConnectionInfoPtr getWSInfo(const Ice::HeaderDict&) const; virtual void checkSendSize(const Buffer&); virtual void setBufferSize(int rcvSize, int sndSize); @@ -56,8 +54,6 @@ private: TcpTransceiver(const ProtocolInstancePtr&, const StreamSocketPtr&); virtual ~TcpTransceiver(); - void fillConnectionInfo(const Ice::TCPConnectionInfoPtr&) const; - friend class TcpConnector; friend class TcpAcceptor; diff --git a/cpp/src/Ice/UdpEndpointI.cpp b/cpp/src/Ice/UdpEndpointI.cpp index f5b3e20982a..2adf5dc32cc 100644 --- a/cpp/src/Ice/UdpEndpointI.cpp +++ b/cpp/src/Ice/UdpEndpointI.cpp @@ -76,10 +76,24 @@ IceInternal::UdpEndpointI::UdpEndpointI(const ProtocolInstancePtr& instance, Inp s->read(const_cast<bool&>(_compress)); } +void +IceInternal::UdpEndpointI::streamWriteImpl(OutputStream* s) const +{ + IPEndpointI::streamWriteImpl(s); + if(s->getEncoding() == Ice::Encoding_1_0) + { + s->write(Ice::Protocol_1_0); + s->write(Ice::Encoding_1_0); + } + // Not transmitted. + //s->write(_connect); + s->write(_compress); +} + EndpointInfoPtr IceInternal::UdpEndpointI::getInfo() const { - Ice::UDPEndpointInfoPtr info = ICE_MAKE_SHARED(InfoI<Ice::UDPEndpointInfo>, + Ice::UDPEndpointInfoPtr info = ICE_MAKE_SHARED(InfoI<Ice::UDPEndpointInfo>, ICE_DYNAMIC_CAST(UdpEndpointI, shared_from_this())); fillEndpointInfo(info.get()); return info; @@ -287,20 +301,6 @@ IceInternal::UdpEndpointI::operator<(const LocalObject& r) const } void -IceInternal::UdpEndpointI::streamWriteImpl(OutputStream* s) const -{ - IPEndpointI::streamWriteImpl(s); - if(s->getEncoding() == Ice::Encoding_1_0) - { - s->write(Ice::Protocol_1_0); - s->write(Ice::Encoding_1_0); - } - // Not transmitted. - //s->write(_connect); - s->write(_compress); -} - -void IceInternal::UdpEndpointI::hashInit(Ice::Int& h) const { IPEndpointI::hashInit(h); @@ -463,7 +463,7 @@ IceInternal::UdpEndpointFactory::destroy() } EndpointFactoryPtr -IceInternal::UdpEndpointFactory::clone(const ProtocolInstancePtr& instance) const +IceInternal::UdpEndpointFactory::clone(const ProtocolInstancePtr& instance, const EndpointFactoryPtr&) const { return new UdpEndpointFactory(instance); } diff --git a/cpp/src/Ice/UdpEndpointI.h b/cpp/src/Ice/UdpEndpointI.h index d534c52c5bb..883b725e688 100644 --- a/cpp/src/Ice/UdpEndpointI.h +++ b/cpp/src/Ice/UdpEndpointI.h @@ -27,6 +27,8 @@ public: UdpEndpointI(const ProtocolInstancePtr&); UdpEndpointI(const ProtocolInstancePtr&, Ice::InputStream*); + virtual void streamWriteImpl(Ice::OutputStream*) const; + virtual Ice::EndpointInfoPtr getInfo() const; virtual Ice::Int timeout() const; @@ -46,14 +48,13 @@ public: virtual bool operator==(const Ice::LocalObject&) const; virtual bool operator<(const Ice::LocalObject&) const; #endif - + UdpEndpointIPtr endpoint(const UdpTransceiverPtr&) const; using IPEndpointI::connectionId; protected: - virtual void streamWriteImpl(Ice::OutputStream*) const; virtual void hashInit(Ice::Int&) const; virtual void fillEndpointInfo(Ice::IPEndpointInfo*) const; virtual bool checkOption(const std::string&, const std::string&, const std::string&); @@ -85,7 +86,7 @@ public: virtual EndpointIPtr read(Ice::InputStream*) const; virtual void destroy(); - virtual EndpointFactoryPtr clone(const ProtocolInstancePtr&) const; + virtual EndpointFactoryPtr clone(const ProtocolInstancePtr&, const EndpointFactoryPtr&) const; private: diff --git a/cpp/src/Ice/UdpTransceiver.cpp b/cpp/src/Ice/UdpTransceiver.cpp index 998ba5cf58f..4c1c277829f 100644..100755 --- a/cpp/src/Ice/UdpTransceiver.cpp +++ b/cpp/src/Ice/UdpTransceiver.cpp @@ -40,11 +40,11 @@ IceInternal::UdpTransceiver::getNativeInfo() return this; } - -#if defined(ICE_USE_IOCP) +#if defined(ICE_USE_IOCP) || defined(ICE_OS_WINRT) AsyncInfo* IceInternal::UdpTransceiver::getAsyncInfo(SocketOperation status) { +#if defined(ICE_USE_IOCP) switch(status) { case SocketOperationRead: @@ -55,26 +55,9 @@ IceInternal::UdpTransceiver::getAsyncInfo(SocketOperation status) assert(false); return 0; } -} #elif defined(ICE_OS_WINRT) -void -IceInternal::UdpTransceiver::setCompletedHandler(SocketOperationCompletedHandler^ handler) -{ - _completedHandler = handler; - _writeOperationCompletedHandler = ref new AsyncOperationCompletedHandler<unsigned int>( - [=] (IAsyncOperation<unsigned int>^ operation, Windows::Foundation::AsyncStatus status) - { - if(status != Windows::Foundation::AsyncStatus::Completed) - { - _write.count = SOCKET_ERROR; - _write.error = operation->ErrorCode.Value; - } - else - { - _write.count = static_cast<int>(operation->GetResults()); - } - _completedHandler(SocketOperationWrite); - }); + return &_write; +#endif } #endif @@ -93,7 +76,15 @@ IceInternal::UdpTransceiver::initialize(Buffer& /*readBuffer*/, Buffer& /*writeB #elif defined(ICE_OS_WINRT) if(_write.count == SOCKET_ERROR) { - checkConnectErrorCode(__FILE__, __LINE__, _write.error, _addr.host); + try + { + checkConnectErrorCode(__FILE__, __LINE__, _write.error); + } + catch(Ice::DNSException& ex) + { + ex.host = IceUtil::wstringToString(_addr.host->RawName->Data(), IceUtil::getProcessStringConverter()); + throw; + } } #else doFinishConnect(_fd); @@ -124,11 +115,10 @@ IceInternal::UdpTransceiver::close() if(_readPending) { assert(_received.empty()); - _completedHandler(SocketOperationRead); + completed(SocketOperationRead); _readPending = false; } _received.clear(); - _completedHandler = nullptr; #endif assert(_fd != INVALID_SOCKET); @@ -394,7 +384,6 @@ IceInternal::UdpTransceiver::startWrite(Buffer& buf) auto operation = safe_cast<DatagramSocket^>(_fd)->ConnectAsync(_addr.host, _addr.port); if(!checkIfErrorOrCompleted(SocketOperationConnect, operation)) { - SocketOperationCompletedHandler^ completed = _completedHandler; operation->Completed = ref new AsyncActionCompletedHandler( [=] (IAsyncAction^ info, Windows::Foundation::AsyncStatus status) { @@ -422,7 +411,6 @@ IceInternal::UdpTransceiver::startWrite(Buffer& buf) auto operation = safe_cast<DatagramSocket^>(_fd)->GetOutputStreamAsync(_addr.host, _addr.port); if(!checkIfErrorOrCompleted(SocketOperationConnect, operation)) { - SocketOperationCompletedHandler^ completed = _completedHandler; operation->Completed = ref new AsyncOperationCompletedHandler<IOutputStream^>( [=] (IAsyncOperation<IOutputStream^>^ info, Windows::Foundation::AsyncStatus status) { @@ -456,7 +444,7 @@ IceInternal::UdpTransceiver::startWrite(Buffer& buf) } catch(Platform::Exception^ ex) { - checkConnectErrorCode(__FILE__, __LINE__, ex->HResult, _addr.host); + checkConnectErrorCode(__FILE__, __LINE__, ex->HResult); } return false; } @@ -464,7 +452,6 @@ IceInternal::UdpTransceiver::startWrite(Buffer& buf) { try { - SocketOperationCompletedHandler^ completed = _completedHandler; DatagramSocket^ fd = safe_cast<DatagramSocket^>(_fd); concurrency::create_task(fd->GetOutputStreamAsync(_peerAddr.host, _peerAddr.port)).then( [=,&buf](concurrency::task<IOutputStream^> task) @@ -474,35 +461,18 @@ IceInternal::UdpTransceiver::startWrite(Buffer& buf) DataWriter^ writer = ref new DataWriter(task.get()); writer->WriteBytes(ref new Array<unsigned char>(&*buf.i, static_cast<int>(buf.b.size()))); DataWriterStoreOperation^ operation = writer->StoreAsync(); - - Windows::Foundation::AsyncStatus status = operation->Status; - if(status == Windows::Foundation::AsyncStatus::Completed) - { - // - // NOTE: unlike other methods, it's important to modify _write.count - // _before_ calling checkIfErrorOrCompleted since this isn't called - // with the connection mutex but from a Windows thread pool thread. - // So we can't modify the _write structure after calling the - // completed callback. - // - _write.count = operation->GetResults(); - completed(SocketOperationWrite); - } - else if(status == Windows::Foundation::AsyncStatus::Started) - { - operation->Completed = _writeOperationCompletedHandler; - } - else - { - if(_state < StateConnected) - { - checkConnectErrorCode(__FILE__, __LINE__, operation->ErrorCode.Value, _addr.host); - } - else - { - checkErrorCode(__FILE__, __LINE__, operation->ErrorCode.Value); - } - } + if(operation->Status == Windows::Foundation::AsyncStatus::Completed) + { + // + // NOTE: unlike other methods, it's important to modify _write.count + // _before_ calling checkIfErrorOrCompleted since this isn't called + // with the connection mutex but from a Windows thread pool thread. + // So we can't modify the _write structure after calling the + // completed callback. + // + _write.count = operation->GetResults(); + } + queueOperation(SocketOperationWrite, operation); } catch(Platform::Exception^ pex) { @@ -523,15 +493,7 @@ IceInternal::UdpTransceiver::startWrite(Buffer& buf) try { _writer->WriteBytes(ref new Array<unsigned char>(&*buf.i, static_cast<int>(buf.b.size()))); - DataWriterStoreOperation^ operation = _writer->StoreAsync(); - if(checkIfErrorOrCompleted(SocketOperationWrite, operation)) - { - _write.count = operation->GetResults(); - } - else - { - operation->Completed = _writeOperationCompletedHandler; - } + queueOperation(SocketOperationWrite, _writer->StoreAsync()); } catch(Platform::Exception^ ex) { @@ -675,7 +637,7 @@ IceInternal::UdpTransceiver::startRead(Buffer& buf) assert(!_readPending); if(!_received.empty()) { - _completedHandler(SocketOperationRead); + completed(SocketOperationRead); } else { @@ -1147,42 +1109,6 @@ IceInternal::UdpTransceiver::setBufSize(int rcvSize, int sndSize) } #ifdef ICE_OS_WINRT -bool -IceInternal::UdpTransceiver::checkIfErrorOrCompleted(SocketOperation op, IAsyncInfo^ info) -{ - // - // NOTE: It's important to only check for info->Status once as it - // might change during the checks below (the Status can be changed - // by the Windows thread pool concurrently). - // - // We consider that a canceled async status is the same as an - // error. A canceled async status can occur if there's a timeout - // and the socket is closed. - // - Windows::Foundation::AsyncStatus status = info->Status; - if(status == Windows::Foundation::AsyncStatus::Completed) - { - _completedHandler(op); - return true; - } - else if(status == Windows::Foundation::AsyncStatus::Started) - { - return false; - } - else - { - if(_state < StateConnected) - { - checkConnectErrorCode(__FILE__, __LINE__, info->ErrorCode.Value, _addr.host); - } - else - { - checkErrorCode(__FILE__, __LINE__, info->ErrorCode.Value); - } - return true; // Prevent compiler warning. - } -} - void IceInternal::UdpTransceiver::appendMessage(DatagramSocketMessageReceivedEventArgs^ args) { @@ -1202,7 +1128,7 @@ IceInternal::UdpTransceiver::appendMessage(DatagramSocketMessageReceivedEventArg // if(_readPending) { - _completedHandler(SocketOperationRead); + completed(SocketOperationRead); _readPending = false; } } diff --git a/cpp/src/Ice/UdpTransceiver.h b/cpp/src/Ice/UdpTransceiver.h index fc38da8795a..84b600d68c2 100644 --- a/cpp/src/Ice/UdpTransceiver.h +++ b/cpp/src/Ice/UdpTransceiver.h @@ -38,10 +38,8 @@ class UdpTransceiver : public Transceiver, public NativeInfo public: virtual NativeInfoPtr getNativeInfo(); -#if defined(ICE_USE_IOCP) +#if defined(ICE_USE_IOCP) || defined(ICE_OS_WINRT) virtual AsyncInfo* getAsyncInfo(SocketOperation); -#elif defined(ICE_OS_WINRT) - virtual void setCompletedHandler(SocketOperationCompletedHandler^); #endif virtual SocketOperation initialize(Buffer&, Buffer&); @@ -80,7 +78,6 @@ private: void setBufSize(int, int); #ifdef ICE_OS_WINRT - bool checkIfErrorOrCompleted(SocketOperation, Windows::Foundation::IAsyncInfo^); void appendMessage(Windows::Networking::Sockets::DatagramSocketMessageReceivedEventArgs^); Windows::Networking::Sockets::DatagramSocketMessageReceivedEventArgs^ readMessage(); #endif @@ -112,12 +109,7 @@ private: socklen_t _readAddrLen; #elif defined(ICE_OS_WINRT) AsyncInfo _write; - Windows::Storage::Streams::DataWriter^ _writer; - - SocketOperationCompletedHandler^ _completedHandler; - Windows::Foundation::AsyncOperationCompletedHandler<unsigned int>^ _writeOperationCompletedHandler; - IceUtil::Mutex _mutex; bool _readPending; std::deque<Windows::Networking::Sockets::DatagramSocketMessageReceivedEventArgs^> _received; diff --git a/cpp/src/Ice/WSAcceptor.cpp b/cpp/src/Ice/WSAcceptor.cpp index 2237d6807d7..d72414dae60 100644 --- a/cpp/src/Ice/WSAcceptor.cpp +++ b/cpp/src/Ice/WSAcceptor.cpp @@ -21,18 +21,12 @@ IceInternal::WSAcceptor::getNativeInfo() return _delegate->getNativeInfo(); } -#if defined(ICE_USE_IOCP) +#if defined(ICE_USE_IOCP) || defined(ICE_OS_WINRT) IceInternal::AsyncInfo* IceInternal::WSAcceptor::getAsyncInfo(IceInternal::SocketOperation status) { return _delegate->getNativeInfo()->getAsyncInfo(status); } -#elif defined(ICE_OS_WINRT) -void -IceInternal::WSAcceptor::setCompletedHandler(IceInternal::SocketOperationCompletedHandler^ handler) -{ - _delegate->getNativeInfo()->setCompletedHandler(handler); -} #endif void diff --git a/cpp/src/Ice/WSAcceptor.h b/cpp/src/Ice/WSAcceptor.h index 8aef5a8ddff..0b389f6a210 100644 --- a/cpp/src/Ice/WSAcceptor.h +++ b/cpp/src/Ice/WSAcceptor.h @@ -26,10 +26,8 @@ class WSAcceptor : public Acceptor, public NativeInfo public: virtual NativeInfoPtr getNativeInfo(); -#if defined(ICE_USE_IOCP) +#if defined(ICE_USE_IOCP) || defined(ICE_OS_WINRT) virtual AsyncInfo* getAsyncInfo(SocketOperation); -#elif defined(ICE_OS_WINRT) - virtual void setCompletedHandler(SocketOperationCompletedHandler^); #endif virtual void close(); @@ -43,8 +41,6 @@ public: virtual std::string toString() const; virtual std::string toDetailedString() const; - virtual AcceptorPtr delegate() const { return _delegate; } - private: WSAcceptor(const WSEndpointPtr&, const ProtocolInstancePtr&, const AcceptorPtr&); diff --git a/cpp/src/Ice/WSConnector.cpp b/cpp/src/Ice/WSConnector.cpp index 91e6a9a7eed..beec5f0ab70 100644 --- a/cpp/src/Ice/WSConnector.cpp +++ b/cpp/src/Ice/WSConnector.cpp @@ -19,7 +19,7 @@ using namespace IceInternal; TransceiverPtr IceInternal::WSConnector::connect() { - return new WSTransceiver(_instance, _delegate->connect(), _host, _port, _resource); + return new WSTransceiver(_instance, _delegate->connect(), _host, _resource); } Short @@ -102,9 +102,9 @@ IceInternal::WSConnector::operator<(const Connector& r) const return false; } -IceInternal::WSConnector::WSConnector(const ProtocolInstancePtr& instance, const ConnectorPtr& del, const string& host, - int port, const string& resource) : - _instance(instance), _delegate(del), _host(host), _port(port), _resource(resource) +IceInternal::WSConnector::WSConnector(const ProtocolInstancePtr& instance, const ConnectorPtr& del, const string& host, + const string& resource) : + _instance(instance), _delegate(del), _host(host), _resource(resource) { } diff --git a/cpp/src/Ice/WSConnector.h b/cpp/src/Ice/WSConnector.h index 3c26a06ab45..176ec9d770c 100644 --- a/cpp/src/Ice/WSConnector.h +++ b/cpp/src/Ice/WSConnector.h @@ -34,15 +34,14 @@ public: virtual bool operator<(const Connector&) const; - WSConnector(const ProtocolInstancePtr&, const ConnectorPtr&, const std::string&, int, const std::string&); + WSConnector(const ProtocolInstancePtr&, const ConnectorPtr&, const std::string&, const std::string&); virtual ~WSConnector(); private: - + const ProtocolInstancePtr _instance; const ConnectorPtr _delegate; const std::string _host; - const int _port; const std::string _resource; }; diff --git a/cpp/src/Ice/WSEndpoint.cpp b/cpp/src/Ice/WSEndpoint.cpp index b42f770bc05..48a9ede3c37 100644 --- a/cpp/src/Ice/WSEndpoint.cpp +++ b/cpp/src/Ice/WSEndpoint.cpp @@ -22,20 +22,36 @@ using namespace std; using namespace Ice; using namespace IceInternal; +namespace +{ + +Ice::IPEndpointInfoPtr +getIPEndpointInfo(const Ice::EndpointInfoPtr& info) +{ + for(Ice::EndpointInfoPtr p = info; p; p = p->underlying) + { + Ice::IPEndpointInfoPtr ipInfo = ICE_DYNAMIC_CAST(Ice::IPEndpointInfo, p); + if(ipInfo) + { + return ipInfo; + } + } + return ICE_NULLPTR; +} + +} + #ifndef ICE_CPP11_MAPPING IceUtil::Shared* IceInternal::upCast(WSEndpoint* p) { return p; } #endif IceInternal::WSEndpoint::WSEndpoint(const ProtocolInstancePtr& instance, const EndpointIPtr& del, const string& res) : - _instance(instance), - _delegate(ICE_DYNAMIC_CAST(IPEndpointI, del)), - _resource(res) + _instance(instance), _delegate(del), _resource(res) { } IceInternal::WSEndpoint::WSEndpoint(const ProtocolInstancePtr& inst, const EndpointIPtr& del, vector<string>& args) : - _instance(inst), - _delegate(ICE_DYNAMIC_CAST(IPEndpointI, del)) + _instance(inst), _delegate(del) { initWithOptions(args); @@ -46,8 +62,7 @@ IceInternal::WSEndpoint::WSEndpoint(const ProtocolInstancePtr& inst, const Endpo } IceInternal::WSEndpoint::WSEndpoint(const ProtocolInstancePtr& instance, const EndpointIPtr& del, InputStream* s) : - _instance(instance), - _delegate(ICE_DYNAMIC_CAST(IPEndpointI, del)) + _instance(instance), _delegate(del) { s->read(const_cast<string&>(_resource), false); } @@ -55,13 +70,12 @@ IceInternal::WSEndpoint::WSEndpoint(const ProtocolInstancePtr& instance, const E Ice::EndpointInfoPtr IceInternal::WSEndpoint::getInfo() const { -#ifdef ICE_CPP11_MAPPING - assert(dynamic_pointer_cast<WSEndpointDelegate>(_delegate)); - return dynamic_pointer_cast<WSEndpointDelegate>(_delegate)->getWSInfo(_resource); -#else - assert(dynamic_cast<WSEndpointDelegate*>(_delegate.get())); - return dynamic_cast<WSEndpointDelegate*>(_delegate.get())->getWSInfo(_resource); -#endif + WSEndpointInfoPtr info = ICE_MAKE_SHARED(InfoI<Ice::WSEndpointInfo>, shared_from_this()); + info->underlying = _delegate->getInfo(); + info->compress = info->underlying->compress; + info->timeout = info->underlying->timeout; + info->resource = _resource; + return info; } Ice::Short @@ -77,12 +91,10 @@ IceInternal::WSEndpoint::protocol() const } void -IceInternal::WSEndpoint::streamWrite(OutputStream* s) const +IceInternal::WSEndpoint::streamWriteImpl(OutputStream* s) const { - s->startEncapsulation(); _delegate->streamWriteImpl(s); s->write(_resource, false); - s->endEncapsulation(); } Int @@ -169,8 +181,8 @@ IceInternal::WSEndpoint::connectors_async(Ice::EndpointSelectionType selType, public: CallbackI(const EndpointI_connectorsPtr& callback, const ProtocolInstancePtr& instance, - const string& host, int port, const string& resource) : - _callback(callback), _instance(instance), _host(host), _port(port), _resource(resource) + const string& host, const string& resource) : + _callback(callback), _instance(instance), _host(host), _resource(resource) { } @@ -179,7 +191,7 @@ IceInternal::WSEndpoint::connectors_async(Ice::EndpointSelectionType selType, vector<ConnectorPtr> connectors = c; for(vector<ConnectorPtr>::iterator p = connectors.begin(); p != connectors.end(); ++p) { - *p = new WSConnector(_instance, *p, _host, _port, _resource); + *p = new WSConnector(_instance, *p, _host, _resource); } _callback->connectors(connectors); } @@ -194,11 +206,16 @@ IceInternal::WSEndpoint::connectors_async(Ice::EndpointSelectionType selType, const EndpointI_connectorsPtr _callback; const ProtocolInstancePtr _instance; const string _host; - const int _port; const string _resource; }; - _delegate->connectors_async(selType, ICE_MAKE_SHARED(CallbackI, callback, _instance, _delegate->host(), - _delegate->port(), _resource)); + + ostringstream host; + IPEndpointInfoPtr info = getIPEndpointInfo(_delegate->getInfo()); + if(info) + { + host << info->host << ":" << info->port; + } + _delegate->connectors_async(selType, ICE_MAKE_SHARED(CallbackI, callback, _instance, host.str(), _resource)); } AcceptorPtr @@ -275,12 +292,6 @@ IceInternal::WSEndpoint::options() const return s.str(); } -EndpointIPtr -IceInternal::WSEndpoint::delegate() const -{ - return ICE_DYNAMIC_CAST(EndpointI, _delegate); -} - bool #ifdef ICE_CPP11_MAPPING IceInternal::WSEndpoint::operator==(const Endpoint& r) const @@ -322,7 +333,7 @@ IceInternal::WSEndpoint::operator<(const Ice::LocalObject& r) const const WSEndpoint* p = dynamic_cast<const WSEndpoint*>(&r); if(!p) { - const EndpointI* e = dynamic_cast<const WSEndpoint*>(&r); + const EndpointI* e = dynamic_cast<const EndpointI*>(&r); if(!e) { return false; @@ -354,7 +365,6 @@ IceInternal::WSEndpoint::operator<(const Ice::LocalObject& r) const } return false; - } bool @@ -382,8 +392,7 @@ IceInternal::WSEndpoint::checkOption(const string& option, const string& argumen } IceInternal::WSEndpointFactory::WSEndpointFactory(const ProtocolInstancePtr& instance, const EndpointFactoryPtr& del) : - _instance(instance), - _delegate(del) + _instance(instance), _delegate(del) { } @@ -423,8 +432,7 @@ IceInternal::WSEndpointFactory::destroy() } EndpointFactoryPtr -IceInternal::WSEndpointFactory::clone(const ProtocolInstancePtr&) const +IceInternal::WSEndpointFactory::clone(const ProtocolInstancePtr& instance, const EndpointFactoryPtr& delegate) const { - assert(false); // We don't support cloning this transport. - return 0; + return new WSEndpointFactory(instance, delegate); } diff --git a/cpp/src/Ice/WSEndpoint.h b/cpp/src/Ice/WSEndpoint.h index 8216902d3f9..a247219409d 100644 --- a/cpp/src/Ice/WSEndpoint.h +++ b/cpp/src/Ice/WSEndpoint.h @@ -20,17 +20,6 @@ namespace IceInternal { -// -// Delegate interface implemented by TcpEndpoint or IceSSL::Endpoint or any endpoint that WS can -// delegate to. -// -class ICE_API WSEndpointDelegate : public virtual IceUtil::Shared -{ -public: - - virtual Ice::EndpointInfoPtr getWSInfo(const std::string&) const = 0; -}; - class WSEndpoint : public EndpointI, public Ice::EnableSharedFromThis<WSEndpoint> { public: @@ -39,10 +28,11 @@ public: WSEndpoint(const ProtocolInstancePtr&, const EndpointIPtr&, std::vector<std::string>&); WSEndpoint(const ProtocolInstancePtr&, const EndpointIPtr&, Ice::InputStream*); + virtual void streamWriteImpl(Ice::OutputStream*) const; + virtual Ice::EndpointInfoPtr getInfo() const; virtual Ice::Short type() const; virtual const std::string& protocol() const; - virtual void streamWrite(Ice::OutputStream*) const; virtual Ice::Int timeout() const; virtual EndpointIPtr timeout(Ice::Int) const; @@ -62,7 +52,6 @@ public: virtual ::Ice::Int hash() const; virtual std::string options() const; - EndpointIPtr delegate() const; WSEndpointPtr endpoint(const EndpointIPtr&) const; #ifdef ICE_CPP11_MAPPING @@ -83,7 +72,7 @@ private: // All members are const, because endpoints are immutable. // const ProtocolInstancePtr _instance; - const IPEndpointIPtr _delegate; + const EndpointIPtr _delegate; const std::string _resource; }; @@ -100,7 +89,7 @@ public: virtual EndpointIPtr read(Ice::InputStream*) const; virtual void destroy(); - virtual EndpointFactoryPtr clone(const ProtocolInstancePtr&) const; + virtual EndpointFactoryPtr clone(const ProtocolInstancePtr&, const EndpointFactoryPtr&) const; private: diff --git a/cpp/src/Ice/WSTransceiver.cpp b/cpp/src/Ice/WSTransceiver.cpp index 5c1b44491ef..24d97b89920 100644 --- a/cpp/src/Ice/WSTransceiver.cpp +++ b/cpp/src/Ice/WSTransceiver.cpp @@ -184,18 +184,12 @@ IceInternal::WSTransceiver::getNativeInfo() return _delegate->getNativeInfo(); } -#if defined(ICE_USE_IOCP) +#if defined(ICE_USE_IOCP) || defined(ICE_OS_WINRT) AsyncInfo* IceInternal::WSTransceiver::getAsyncInfo(SocketOperation status) { return _delegate->getNativeInfo()->getAsyncInfo(status); } -#elif defined(ICE_OS_WINRT) -void -IceInternal::WSTransceiver::setCompletedHandler(IceInternal::SocketOperationCompletedHandler^ handler) -{ - _delegate->getNativeInfo()->setCompletedHandler(handler); -} #endif SocketOperation @@ -236,7 +230,7 @@ IceInternal::WSTransceiver::initialize(Buffer& readBuffer, Buffer& writeBuffer) // ostringstream out; out << "GET " << _resource << " HTTP/1.1\r\n" - << "Host: " << _host << ":" << _port << "\r\n" + << "Host: " << _host << "\r\n" << "Upgrade: websocket\r\n" << "Connection: Upgrade\r\n" << "Sec-WebSocket-Protocol: " << _iceProtocol << "\r\n" @@ -873,8 +867,10 @@ IceInternal::WSTransceiver::toDetailedString() const Ice::ConnectionInfoPtr IceInternal::WSTransceiver::getInfo() const { - assert(dynamic_cast<WSTransceiverDelegate*>(_delegate.get())); - return dynamic_cast<WSTransceiverDelegate*>(_delegate.get())->getWSInfo(_parser->getHeaders()); + WSConnectionInfoPtr info = ICE_MAKE_SHARED(WSConnectionInfo); + info->underlying = _delegate->getInfo(); + info->headers = _parser->getHeaders(); + return info; } void @@ -890,11 +886,10 @@ IceInternal::WSTransceiver::setBufferSize(int rcvSize, int sndSize) } IceInternal::WSTransceiver::WSTransceiver(const ProtocolInstancePtr& instance, const TransceiverPtr& del, - const string& host, int port, const string& resource) : + const string& host, const string& resource) : _instance(instance), _delegate(del), _host(host), - _port(port), _resource(resource), _incoming(false), _state(StateInitializeDelegate), @@ -924,7 +919,6 @@ IceInternal::WSTransceiver::WSTransceiver(const ProtocolInstancePtr& instance, c IceInternal::WSTransceiver::WSTransceiver(const ProtocolInstancePtr& instance, const TransceiverPtr& del) : _instance(instance), _delegate(del), - _port(-1), _incoming(true), _state(StateInitializeDelegate), _parser(new HttpParser), diff --git a/cpp/src/Ice/WSTransceiver.h b/cpp/src/Ice/WSTransceiver.h index db01cd309b8..7b6a7ffe5e6 100644 --- a/cpp/src/Ice/WSTransceiver.h +++ b/cpp/src/Ice/WSTransceiver.h @@ -24,26 +24,13 @@ namespace IceInternal class ConnectorI; class AcceptorI; -// -// Delegate interface implemented by TcpTransceiver or IceSSL::Transceiver or any transport that WS can -// delegate to. -// -class ICE_API WSTransceiverDelegate : public virtual IceUtil::Shared -{ -public: - - virtual Ice::ConnectionInfoPtr getWSInfo(const Ice::HeaderDict&) const = 0; -}; - class WSTransceiver : public Transceiver { public: virtual NativeInfoPtr getNativeInfo(); -#if defined(ICE_USE_IOCP) +#if defined(ICE_USE_IOCP) || defined(ICE_OS_WINRT) virtual AsyncInfo* getAsyncInfo(SocketOperation); -#elif defined(ICE_OS_WINRT) - virtual void setCompletedHandler(SocketOperationCompletedHandler^); #endif virtual SocketOperation initialize(Buffer&, Buffer&); @@ -70,7 +57,7 @@ public: private: - WSTransceiver(const ProtocolInstancePtr&, const TransceiverPtr&, const std::string&, int, const std::string&); + WSTransceiver(const ProtocolInstancePtr&, const TransceiverPtr&, const std::string&, const std::string&); WSTransceiver(const ProtocolInstancePtr&, const TransceiverPtr&); virtual ~WSTransceiver(); @@ -92,7 +79,6 @@ private: const ProtocolInstancePtr _instance; const TransceiverPtr _delegate; const std::string _host; - const int _port; const std::string _resource; const bool _incoming; diff --git a/cpp/src/Ice/ios/RegisterPluginsInit.cpp b/cpp/src/Ice/ios/RegisterPluginsInit.cpp deleted file mode 100644 index 712f4dcc765..00000000000 --- a/cpp/src/Ice/ios/RegisterPluginsInit.cpp +++ /dev/null @@ -1,30 +0,0 @@ -// ********************************************************************** -// -// Copyright (c) 2003-2016 ZeroC, Inc. All rights reserved. -// -// This copy of Ice is licensed to you under the terms described in the -// ICE_LICENSE file included in this distribution. -// -// ********************************************************************** - -#include <Ice/RegisterPluginsInit.h> -#include <Ice/CommunicatorF.h> -#include <Ice/Initialize.h> - -extern "C" -{ - -Ice::Plugin* createIceUDP(const Ice::CommunicatorPtr&, const std::string&, const Ice::StringSeq&); -Ice::Plugin* createIceTCP(const Ice::CommunicatorPtr&, const std::string&, const Ice::StringSeq&); -Ice::Plugin* createIceSSL(const Ice::CommunicatorPtr&, const std::string&, const Ice::StringSeq&); -Ice::Plugin* createIceIAP(const Ice::CommunicatorPtr&, const std::string&, const Ice::StringSeq&); - -}; - -IceInternal::RegisterPluginsInit::RegisterPluginsInit() -{ - Ice::registerPluginFactory("IceUDP", createIceUDP, true); - Ice::registerPluginFactory("IceTCP", createIceTCP, true); - Ice::registerPluginFactory("IceSSL", createIceSSL, true); - Ice::registerPluginFactory("IceIAP", createIceIAP, true); -} diff --git a/cpp/src/Ice/ios/StreamEndpointI.cpp b/cpp/src/Ice/ios/StreamEndpointI.cpp index cdc59f6a41a..78e8dab2cff 100644 --- a/cpp/src/Ice/ios/StreamEndpointI.cpp +++ b/cpp/src/Ice/ios/StreamEndpointI.cpp @@ -23,10 +23,7 @@ #include <Ice/HashUtil.h> #include <Ice/NetworkProxy.h> -#include <IceSSL/EndpointInfo.h> - #include <CoreFoundation/CoreFoundation.h> -#include <Security/Security.h> #include <fstream> @@ -44,25 +41,10 @@ createIceTCP(const CommunicatorPtr& com, const string&, const StringSeq&) return new EndpointFactoryPlugin(com, new IceObjC::StreamEndpointFactory(tcpInstance)); } -Plugin* -createIceSSL(const CommunicatorPtr& com, const string&, const StringSeq&) -{ - IceObjC::InstancePtr sslInstance = new IceObjC::Instance(com, SSLEndpointType, "ssl", true); - return new EndpointFactoryPlugin(com, new IceObjC::StreamEndpointFactory(sslInstance)); -} - } -namespace Ice -{ - -void -registerIceSSL(bool) +namespace { - // Nothing to do, we always register IceSSL -} - -} inline CFStringRef toCFString(const string& s) @@ -70,247 +52,15 @@ toCFString(const string& s) return CFStringCreateWithCString(NULL, s.c_str(), kCFStringEncodingUTF8); } -inline int -hexValue(char c) -{ - if(c >= '0' && c <= '9') - { - return c - '0'; - } - else if(c >= 'A' && c <= 'F') - { - return (c - 'A') + 10; - } - else if(c >= 'a' && c <= 'f') - { - return (c - 'a') + 10; - } - return -1; -} - -inline CFDataRef -parseKey(const string& keyStr) -{ - int i = 0, j = 0; - const char* m = keyStr.c_str(); - CFMutableDataRef data = CFDataCreateMutable(0, 160); - unsigned char buf[160]; - while(i < (int)keyStr.size()) - { - if(isspace(m[i]) || m[i] == ':') - { - ++i; - continue; - } - else if(i == (int)keyStr.size() - 1) - { - CFRelease(data); - return 0; // Not enough bytes. - } - - int vh = hexValue(m[i++]); - int vl = hexValue(m[i++]); - if(vh < 0 || vl < 0) - { - CFRelease(data); - return 0; - } - buf[j] = vh << 4; - buf[j++] += vl; - - if(j == sizeof(buf)) - { - CFDataAppendBytes(data, (UInt8*)buf, j); - j = 0; - } - } - - if(j > 0) - { - CFDataAppendBytes(data, buf, j); - } - - return data; -} - -namespace -{ - -CFDataRef -readCert(const string& defaultDir, const string& certFile) -{ - string path; - CFURLRef url = 0; - CFBundleRef bundle = CFBundleGetMainBundle(); - if(bundle) - { - CFStringRef resourceName = toCFString(certFile); - CFStringRef subDirName = toCFString(defaultDir); - url = CFBundleCopyResourceURL(bundle, resourceName, 0, subDirName); - CFRelease(resourceName); - CFRelease(subDirName); - - UInt8 filePath[PATH_MAX]; - if(CFURLGetFileSystemRepresentation(url, true, filePath, sizeof(filePath))) - { - path = string(reinterpret_cast<char*>(filePath)); - } - } - - if(!url || path.empty()) - { - path = defaultDir.empty() ? certFile : defaultDir + "/" + certFile; - } - - FILE *file = fopen(path.c_str(), "rb"); - if(!file) - { - ostringstream os; - os << "IceSSL: unable to open file " << certFile << " (error = " << IceUtilInternal::lastErrorToString() << ")"; - throw InitializationException(__FILE__, __LINE__, os.str()); - } - - fseek(file, 0, SEEK_END); - unsigned long size = ftell(file); - fseek(file, 0, SEEK_SET); - CFMutableDataRef data = CFDataCreateMutable(kCFAllocatorDefault, size); - CFDataSetLength(data, size); - if(fread(CFDataGetMutableBytePtr(data), 1, size, file) != size) - { - CFRelease(data); - ostringstream os; - os << "IceSSL: error while reading file " << certFile; - throw InitializationException(__FILE__, __LINE__, os.str()); - } - fclose(file); - return data; -} - } IceObjC::Instance::Instance(const Ice::CommunicatorPtr& com, Short type, const string& protocol, bool secure) : ProtocolInstance(com, type, protocol, secure), _voip(com->getProperties()->getPropertyAsIntWithDefault("Ice.Voip", 0) > 0), _communicator(com), - _serverSettings(0), - _clientSettings(0), - _proxySettings(0), - _certificateAuthorities(0), - _trustOnlyKeyID(0) + _proxySettings(0) { const Ice::PropertiesPtr properties = com->getProperties(); - if(secure) - { - _clientSettings = CFDictionaryCreateMutable(0, 1, &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); - - string defaultDir = properties->getProperty("IceSSL.DefaultDir"); - string certAuthFile = properties->getProperty("IceSSL.CAs"); - if(certAuthFile.empty()) - { - certAuthFile = properties->getProperty("IceSSL.CertAuthFile"); - } - string certFile = properties->getProperty("IceSSL.CertFile"); - - OSStatus err; - if(!certAuthFile.empty()) - { - CFDataRef cert = readCert(defaultDir, certAuthFile); - if(!cert) - { - InitializationException ex(__FILE__, __LINE__); - ex.reason = "IceSSL: unable to open file " + certAuthFile; - throw ex; - } - - SecCertificateRef result = SecCertificateCreateWithData(0, cert); - CFRelease(cert); - if(!result) - { - InitializationException ex(__FILE__, __LINE__); - ex.reason = "IceSSL: certificate " + certAuthFile + " is not a valid DER-encoded certificate"; - throw ex; - } - - SecCertificateRef certs[] = { result }; - _certificateAuthorities = CFArrayCreate(0, (const void**)certs, 1, &kCFTypeArrayCallBacks); - CFRelease(result); - - // The root CA will be validated by the transceiver. - // NOTE: on the iPhone, setting kCFStreamSSLAllowsAnyRoot = true isn't enough. - //CFDictionarySetValue(_clientSettings, kCFStreamSSLAllowsAnyRoot, kCFBooleanTrue); - CFDictionarySetValue(_clientSettings, kCFStreamSSLValidatesCertificateChain, kCFBooleanFalse); - } - else if(properties->getPropertyAsInt("IceSSL.UsePlatformCAs") <= 0) - { - // Setup an empty list of Root CAs to not use the system root CAs. - _certificateAuthorities = CFArrayCreate(0, 0, 0, 0); - } - - if(!certFile.empty()) - { - CFDataRef cert = readCert(defaultDir, certFile); - if(!cert) - { - InitializationException ex(__FILE__, __LINE__); - ex.reason = "IceSSL: unable to open file " + certFile; - throw ex; - } - - CFMutableDictionaryRef settings = CFDictionaryCreateMutable(0, 1, &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); - CFStringRef password = toCFString(properties->getProperty("IceSSL.Password")); - CFDictionarySetValue(settings, kSecImportExportPassphrase, password); - CFRelease(password); - - CFArrayRef items = 0; - err = SecPKCS12Import(cert, settings, &items); - CFRelease(cert); - CFRelease(settings); - if(err != noErr) - { - ostringstream os; - os << "IceSSL: unable to import certificate from file " << certFile << " (error = " << err << ")"; - throw InitializationException(__FILE__, __LINE__, os.str()); - } - - SecIdentityRef identity = 0; - if(CFArrayGetCount(items) > 0) - { - identity = (SecIdentityRef)CFDictionaryGetValue((CFDictionaryRef)CFArrayGetValueAtIndex(items, 0), - kSecImportItemIdentity); - } - if(identity == 0) - { - ostringstream os; - os << "IceSSL: couldn't find identity in file " << certFile << " (error = " << err << ")"; - throw InitializationException(__FILE__, __LINE__, os.str()); - } - CFRetain(identity); - CFRelease(items); - - SecIdentityRef identities[] = { identity }; - items = CFArrayCreate(0, (const void**)identities, 1, &kCFTypeArrayCallBacks); - CFDictionarySetValue(_clientSettings, kCFStreamSSLCertificates, items); - CFRelease(identity); - CFRelease(items); - } - - string trustOnly = properties->getProperty("IceSSL.TrustOnly.Client"); - if(!trustOnly.empty()) - { - _trustOnlyKeyID = parseKey(trustOnly); - if(!_trustOnlyKeyID) - { - ostringstream os; - os << "IceSSL: invalid `IceSSL.TrustOnly.Client' property value"; - throw InitializationException(__FILE__, __LINE__, os.str()); - } - } - - _serverSettings = CFDictionaryCreateMutableCopy(0, 0, _clientSettings); - CFDictionarySetValue(_serverSettings, kCFStreamSSLIsServer, kCFBooleanTrue); - } // // Proxy settings @@ -340,22 +90,6 @@ IceObjC::Instance::Instance(const Ice::CommunicatorPtr& com, Short type, const s IceObjC::Instance::~Instance() { - if(_trustOnlyKeyID) - { - CFRelease(_trustOnlyKeyID); - } - if(_serverSettings) - { - CFRelease(_serverSettings); - } - if(_clientSettings) - { - CFRelease(_clientSettings); - } - if(_certificateAuthorities) - { - CFRelease(_certificateAuthorities); - } if(_proxySettings) { CFRelease(_proxySettings); @@ -387,40 +121,6 @@ IceObjC::Instance::setupStreams(CFReadStreamRef readStream, throw Ice::SyscallException(__FILE__, __LINE__); } } - - if(secure()) - { - CFDictionaryRef settings = server ? _serverSettings : _clientSettings; - - if(!CFReadStreamSetProperty(readStream, kCFStreamPropertySocketSecurityLevel, - kCFStreamSocketSecurityLevelNegotiatedSSL) || - !CFWriteStreamSetProperty(writeStream, kCFStreamPropertySocketSecurityLevel, - kCFStreamSocketSecurityLevelNegotiatedSSL)) - { - throw Ice::SecurityException(__FILE__, __LINE__, "couldn't set security level"); - } - - if(!server && properties()->getPropertyAsIntWithDefault("IceSSL.CheckCertName", 1)) - { - settings = CFDictionaryCreateMutableCopy(0, 0, settings); - - CFStringRef h = toCFString(host); - CFDictionarySetValue((CFMutableDictionaryRef)settings, kCFStreamSSLPeerName, h); - CFRelease(h); - } - else - { - CFRetain(settings); - } - - if(!CFReadStreamSetProperty(readStream, kCFStreamPropertySSLSettings, settings) || - !CFWriteStreamSetProperty(writeStream, kCFStreamPropertySSLSettings, settings)) - { - CFRelease(settings); - throw Ice::SecurityException(__FILE__, __LINE__, "couldn't set security options"); - } - CFRelease(settings); - } } IceObjC::Instance* @@ -459,38 +159,10 @@ IceObjC::StreamEndpointI::StreamEndpointI(const InstancePtr& instance, Ice::Inpu EndpointInfoPtr IceObjC::StreamEndpointI::getInfo() const { - IPEndpointInfoPtr info; - if(_instance->secure()) - { - info = ICE_MAKE_SHARED(InfoI<IceSSL::EndpointInfo>, ICE_DYNAMIC_CAST(StreamEndpointI, shared_from_this())); - } - else - { - info = ICE_MAKE_SHARED(InfoI<Ice::TCPEndpointInfo>, ICE_DYNAMIC_CAST(StreamEndpointI, shared_from_this())); - } - fillEndpointInfo(info.get()); - return info; -} - -EndpointInfoPtr -IceObjC::StreamEndpointI::getWSInfo(const string& resource) const -{ - IPEndpointInfoPtr info; - if(_instance->secure()) - { - IceSSL::WSSEndpointInfoPtr i; - i = ICE_MAKE_SHARED(InfoI<IceSSL::WSSEndpointInfo>, ICE_DYNAMIC_CAST(StreamEndpointI, shared_from_this())); - i->resource = resource; - info = i; - } - else - { - Ice::WSEndpointInfoPtr i; - i = ICE_MAKE_SHARED(InfoI<Ice::WSEndpointInfo>, ICE_DYNAMIC_CAST(StreamEndpointI, shared_from_this())); - i->resource = resource; - info = i; - } - fillEndpointInfo(info.get()); + TCPEndpointInfoPtr info = ICE_MAKE_SHARED(InfoI<Ice::TCPEndpointInfo>, shared_from_this()); + IPEndpointI::fillEndpointInfo(info.get()); + info->timeout = _timeout; + info->compress = _compress; return info; } @@ -561,7 +233,7 @@ IceObjC::StreamEndpointI::transceiver() const AcceptorPtr IceObjC::StreamEndpointI::acceptor(const string&) const { - return new StreamAcceptor(ICE_DYNAMIC_CAST(StreamEndpointI, shared_from_this()), _instance, _host, _port); + return new StreamAcceptor(shared_from_this(), _instance, _host, _port); } IceObjC::StreamEndpointIPtr @@ -698,14 +370,6 @@ IceObjC::StreamEndpointI::hashInit(Ice::Int& h) const hashAdd(h, _compress); } -void -IceObjC::StreamEndpointI::fillEndpointInfo(IPEndpointInfo* info) const -{ - IPEndpointI::fillEndpointInfo(info); - info->timeout = _timeout; - info->compress = _compress; -} - bool IceObjC::StreamEndpointI::checkOption(const string& option, const string& argument, const string& endpoint) { @@ -815,7 +479,7 @@ IceObjC::StreamEndpointFactory::destroy() } EndpointFactoryPtr -IceObjC::StreamEndpointFactory::clone(const ProtocolInstancePtr& instance) const +IceObjC::StreamEndpointFactory::clone(const ProtocolInstancePtr& instance, const EndpointFactoryPtr&) const { return new StreamEndpointFactory(_instance->clone(instance)); } diff --git a/cpp/src/Ice/ios/StreamEndpointI.h b/cpp/src/Ice/ios/StreamEndpointI.h index 51d3ab75d78..3dd90551199 100644 --- a/cpp/src/Ice/ios/StreamEndpointI.h +++ b/cpp/src/Ice/ios/StreamEndpointI.h @@ -37,16 +37,6 @@ public: Instance(const Ice::CommunicatorPtr&, Ice::Short, const std::string&, bool); virtual ~Instance(); - CFArrayRef certificateAuthorities() const - { - return _certificateAuthorities; - } - - CFDataRef trustOnlyKeyID() const - { - return _trustOnlyKeyID; - } - const std::string& proxyHost() const { return _proxyHost; @@ -65,12 +55,7 @@ private: const bool _voip; const Ice::CommunicatorPtr _communicator; - CFMutableDictionaryRef _serverSettings; - CFMutableDictionaryRef _clientSettings; CFMutableDictionaryRef _proxySettings; - CFArrayRef _certificateAuthorities; - CFDataRef _trustOnlyKeyID; - std::string _proxyHost; int _proxyPort; }; @@ -86,7 +71,7 @@ typedef ::std::shared_ptr<StreamEndpointI> StreamEndpointIPtr; typedef IceUtil::Handle<StreamEndpointI> StreamEndpointIPtr; #endif -class StreamEndpointI : public IceInternal::IPEndpointI, public IceInternal::WSEndpointDelegate +class StreamEndpointI : public IceInternal::IPEndpointI, public Ice::EnableSharedFromThis<StreamEndpointI> { public: @@ -96,7 +81,6 @@ public: StreamEndpointI(const InstancePtr&, Ice::InputStream*); virtual Ice::EndpointInfoPtr getInfo() const; - virtual Ice::EndpointInfoPtr getWSInfo(const std::string&) const; virtual Ice::Int timeout() const; virtual IceInternal::EndpointIPtr timeout(Ice::Int) const; @@ -121,12 +105,12 @@ public: StreamEndpointIPtr endpoint(const StreamAcceptorPtr&) const; using IPEndpointI::connectionId; + using Ice::EnableSharedFromThis<StreamEndpointI>::shared_from_this; protected: virtual void streamWriteImpl(Ice::OutputStream*) const; virtual void hashInit(Ice::Int&) const; - virtual void fillEndpointInfo(Ice::IPEndpointInfo*) const; virtual bool checkOption(const std::string&, const std::string&, const std::string&); virtual IceInternal::ConnectorPtr createConnector(const IceInternal::Address&, @@ -158,7 +142,8 @@ public: virtual IceInternal::EndpointIPtr read(Ice::InputStream*) const; virtual void destroy(); - virtual IceInternal::EndpointFactoryPtr clone(const IceInternal::ProtocolInstancePtr&) const; + virtual IceInternal::EndpointFactoryPtr clone(const IceInternal::ProtocolInstancePtr&, + const IceInternal::EndpointFactoryPtr&) const; private: diff --git a/cpp/src/Ice/ios/StreamTransceiver.cpp b/cpp/src/Ice/ios/StreamTransceiver.cpp index bc76ffcd059..4fcbec4f400 100644 --- a/cpp/src/Ice/ios/StreamTransceiver.cpp +++ b/cpp/src/Ice/ios/StreamTransceiver.cpp @@ -19,7 +19,6 @@ #include <IceSSL/ConnectionInfo.h> #include <CoreFoundation/CoreFoundation.h> -#include <Security/Security.h> using namespace std; using namespace Ice; @@ -292,13 +291,6 @@ IceObjC::StreamTransceiver::initialize(Buffer& readBuffer, Buffer& writeBuffer) setBlock(_fd, false); setTcpBufSize(_fd, _instance); - - // - // Limit the size of packets passed to SSLWrite/SSLRead to avoid - // blocking and holding too much memory. - // - _maxSendPacketSize = std::max(512, getSendBufferSize(_fd)); - _maxRecvPacketSize = std::max(512, getRecvBufferSize(_fd)); } assert(_state == StateConnected); return SocketOperationNone; @@ -345,7 +337,7 @@ IceObjC::StreamTransceiver::write(Buffer& buf) } // Its impossible for the packetSize to be more than an Int. - size_t packetSize = std::min(static_cast<size_t>(buf.b.end() - buf.i), _maxSendPacketSize); + size_t packetSize = static_cast<size_t>(buf.b.end() - buf.i); while(buf.i != buf.b.end()) { if(!CFWriteStreamCanAcceptBytes(_writeStream)) @@ -353,12 +345,6 @@ IceObjC::StreamTransceiver::write(Buffer& buf) return SocketOperationWrite; } - if(_checkCertificates) - { - _checkCertificates = false; - checkCertificates(); - } - assert(_fd != INVALID_SOCKET); CFIndex ret = CFWriteStreamWrite(_writeStream, reinterpret_cast<const UInt8*>(&*buf.i), packetSize); @@ -401,7 +387,7 @@ IceObjC::StreamTransceiver::read(Buffer& buf) } // Its impossible for the packetSize to be more than an Int. - size_t packetSize = std::min(static_cast<size_t>(buf.b.end() - buf.i), _maxRecvPacketSize); + size_t packetSize = static_cast<size_t>(buf.b.end() - buf.i); while(buf.i != buf.b.end()) { if(!CFReadStreamHasBytesAvailable(_readStream)) @@ -409,12 +395,6 @@ IceObjC::StreamTransceiver::read(Buffer& buf) return SocketOperationRead; } - if(_checkCertificates) - { - _checkCertificates = false; - checkCertificates(); - } - assert(_fd != INVALID_SOCKET); CFIndex ret = CFReadStreamRead(_readStream, reinterpret_cast<UInt8*>(&*buf.i), packetSize); @@ -475,39 +455,11 @@ IceObjC::StreamTransceiver::toDetailedString() const Ice::ConnectionInfoPtr IceObjC::StreamTransceiver::getInfo() const { - if(_instance->secure()) - { - IceSSL::ConnectionInfoPtr info = ICE_MAKE_SHARED(IceSSL::ConnectionInfo); - fillConnectionInfo(info); - info->verified = _state == StateConnected; - return info; - } - else - { - Ice::TCPConnectionInfoPtr info = ICE_MAKE_SHARED(Ice::TCPConnectionInfo); - fillConnectionInfo(info); - return info; - } -} - -Ice::ConnectionInfoPtr -IceObjC::StreamTransceiver::getWSInfo(const Ice::HeaderDict& headers) const -{ - if(_instance->secure()) - { - IceSSL::WSSConnectionInfoPtr info = ICE_MAKE_SHARED(IceSSL::WSSConnectionInfo); - fillConnectionInfo(info); - info->verified = _state == StateConnected; - info->headers = headers; - return info; - } - else - { - Ice::WSConnectionInfoPtr info = ICE_MAKE_SHARED(Ice::WSConnectionInfo); - fillConnectionInfo(info); - info->headers = headers; - return info; - } + Ice::TCPConnectionInfoPtr info = ICE_MAKE_SHARED(Ice::TCPConnectionInfo); + fdToAddressAndPort(_fd, info->localAddress, info->localPort, info->remoteAddress, info->remotePort); + info->rcvSize = getRecvBufferSize(_fd); + info->sndSize = getSendBufferSize(_fd); + return info; } void @@ -535,7 +487,6 @@ IceObjC::StreamTransceiver::StreamTransceiver(const InstancePtr& instance, _readStreamRegistered(false), _writeStreamRegistered(false), _opening(false), - _checkCertificates(instance->secure()), _error(false), _state(StateNeedConnect) { @@ -562,7 +513,6 @@ IceObjC::StreamTransceiver::StreamTransceiver(const InstancePtr& instance, _readStreamRegistered(false), _writeStreamRegistered(false), _opening(false), - _checkCertificates(false), _error(false), _state(StateNeedConnect), _desc(fdToString(fd)) @@ -577,144 +527,6 @@ IceObjC::StreamTransceiver::~StreamTransceiver() } void -IceObjC::StreamTransceiver::checkCertificates() -{ - SecTrustRef trust = (SecTrustRef)CFWriteStreamCopyProperty(_writeStream, kCFStreamPropertySSLPeerTrust); - if(!trust) - { - throw Ice::SecurityException(__FILE__, __LINE__, "unable to obtain trust object"); - } - - try - { - SecPolicyRef policy = 0; - if(_host.empty() || _instance->properties()->getPropertyAsIntWithDefault("IceSSL.CheckCertName", 1) == 0) - { - policy = SecPolicyCreateBasicX509(); - } - else - { - CFStringRef h = CFStringCreateWithCString(NULL, _host.c_str(), kCFStringEncodingUTF8); - policy = SecPolicyCreateSSL(false, h); - CFRelease(h); - } - - OSStatus err = SecTrustSetPolicies(trust, policy); - CFRelease(policy); - if(err != noErr) - { - ostringstream os; - os << "unable to set trust object policy (error = " << err << ")"; - throw Ice::SecurityException(__FILE__, __LINE__, os.str()); - } - - // - // If IceSSL.CertAuthFile is set, we use the certificate authorities from this file - // instead of the ones from the keychain. - // - if((err = SecTrustSetAnchorCertificates(trust, _instance->certificateAuthorities())) != noErr) - { - ostringstream os; - os << "couldn't set root CA certificates with trust object (error = " << err << ")"; - throw Ice::SecurityException(__FILE__, __LINE__, os.str()); - } - - SecTrustResultType result = kSecTrustResultInvalid; - if((err = SecTrustEvaluate(trust, &result)) != noErr) - { - ostringstream os; - os << "unable to evaluate the peer certificate trust (error = " << err << ")"; - throw Ice::SecurityException(__FILE__, __LINE__, os.str()); - } - - // - // The kSecTrustResultUnspecified result indicates that the user didn't set any trust - // settings for the root CA. This is expected if the root CA is provided by the user - // with IceSSL.CertAuthFile or if the user didn't explicitly set any trust settings - // for the certificate. - // - if(result != kSecTrustResultProceed && result != kSecTrustResultUnspecified) - { - ostringstream os; - os << "certificate validation failed (result = " << result << ")"; - throw Ice::SecurityException(__FILE__, __LINE__, os.str()); - } - - if(_instance->trustOnlyKeyID()) - { - if(SecTrustGetCertificateCount(trust) < 0) - { - throw Ice::SecurityException(__FILE__, __LINE__, "unable to obtain peer certificate"); - } - - SecCertificateRef cert = SecTrustGetCertificateAtIndex(trust, 0); - - // - // To check the subject key ID, we add the peer certificate to the keychain with SetItemAdd, - // then we lookup for the cert using the kSecAttrSubjectKeyID. Then we remove the cert from - // the keychain. NOTE: according to the Apple documentation, it should in theory be possible - // to not add/remove the item to the keychain by specifying the kSecMatchItemList key (or - // kSecUseItemList?) when calling SecItemCopyMatching. Unfortunately this doesn't appear to - // work. Similarly, it should be possible to get back the attributes of the certificate - // once it added by setting kSecReturnAttributes in the add query, again this doesn't seem - // to work. - // - CFMutableDictionaryRef query; - query = CFDictionaryCreateMutable(0, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - CFDictionarySetValue(query, kSecClass, kSecClassCertificate); - CFDictionarySetValue(query, kSecValueRef, cert); - err = SecItemAdd(query, 0); - if(err != noErr && err != errSecDuplicateItem) - { - CFRelease(query); - ostringstream os; - os << "unable to add peer certificate to keychain (error = " << err << ")"; - throw Ice::SecurityException(__FILE__, __LINE__, os.str()); - } - CFRelease(query); - - query = CFDictionaryCreateMutable(0, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - CFDictionarySetValue(query, kSecClass, kSecClassCertificate); - CFDictionarySetValue(query, kSecValueRef, cert); - CFDictionarySetValue(query, kSecAttrSubjectKeyID, _instance->trustOnlyKeyID()); - err = SecItemCopyMatching(query, 0); - OSStatus foundErr = err; - CFRelease(query); - - query = CFDictionaryCreateMutable(0, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - CFDictionarySetValue(query, kSecClass, kSecClassCertificate); - CFDictionarySetValue(query, kSecValueRef, cert); - err = SecItemDelete(query); - if(err != noErr) - { - CFRelease(query); - ostringstream os; - os << "unable to remove peer certificate from keychain (error = " << err << ")"; - throw Ice::SecurityException(__FILE__, __LINE__, os.str()); - } - CFRelease(query); - - if(foundErr != noErr) - { - ostringstream os; - os << "the certificate subject key ID doesn't match the `IceSSL.TrustOnly.Client' property "; - os << "(error = " << foundErr << ")"; - throw Ice::SecurityException(__FILE__, __LINE__, os.str()); - } - } - CFRelease(trust); - } - catch(...) - { - if(trust) - { - CFRelease(trust); - } - throw; - } -} - -void IceObjC::StreamTransceiver::checkError(CFErrorRef err, const char* file, int line) { assert(err); @@ -783,11 +595,3 @@ IceObjC::StreamTransceiver::checkError(CFErrorRef err, const char* file, int lin CFRelease(err); throw ex; } - -void -IceObjC::StreamTransceiver::fillConnectionInfo(const Ice::IPConnectionInfoPtr& info) const -{ - fdToAddressAndPort(_fd, info->localAddress, info->localPort, info->remoteAddress, info->remotePort); - info->rcvSize = getRecvBufferSize(_fd); - info->sndSize = getSendBufferSize(_fd); -} diff --git a/cpp/src/Ice/ios/StreamTransceiver.h b/cpp/src/Ice/ios/StreamTransceiver.h index 97578f094d0..e38285451f8 100644 --- a/cpp/src/Ice/ios/StreamTransceiver.h +++ b/cpp/src/Ice/ios/StreamTransceiver.h @@ -29,8 +29,7 @@ namespace IceObjC class Instance; typedef IceUtil::Handle<Instance> InstancePtr; -class StreamTransceiver : public IceInternal::Transceiver, public IceInternal::StreamNativeInfo, - public IceInternal::WSTransceiverDelegate +class StreamTransceiver : public IceInternal::Transceiver, public IceInternal::StreamNativeInfo { enum State { @@ -67,15 +66,12 @@ public: virtual std::string toString() const; virtual std::string toDetailedString() const; virtual Ice::ConnectionInfoPtr getInfo() const; - virtual Ice::ConnectionInfoPtr getWSInfo(const Ice::HeaderDict&) const; virtual void checkSendSize(const IceInternal::Buffer&); virtual void setBufferSize(int, int); private: - void checkCertificates(); void checkError(CFErrorRef, const char*, int); - void fillConnectionInfo(const Ice::IPConnectionInfoPtr&) const; const InstancePtr _instance; const std::string _host; @@ -85,16 +81,12 @@ private: bool _readStreamRegistered; bool _writeStreamRegistered; bool _opening; - bool _checkCertificates; IceUtil::Mutex _mutex; bool _error; State _state; std::string _desc; - - size_t _maxSendPacketSize; - size_t _maxRecvPacketSize; }; } diff --git a/cpp/src/Ice/msbuild/iceuwp++11/iceuwp++11.vcxproj b/cpp/src/Ice/msbuild/iceuwp++11/iceuwp++11.vcxproj index c6fe7a4255b..68b41ffea80 100644 --- a/cpp/src/Ice/msbuild/iceuwp++11/iceuwp++11.vcxproj +++ b/cpp/src/Ice/msbuild/iceuwp++11/iceuwp++11.vcxproj @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="utf-8"?> +<?xml version="1.0" encoding="utf-8"?> <Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|ARM"> @@ -147,6 +147,7 @@ <ClCompile Include="..\..\..\IceUtil\Shared.cpp" /> <ClCompile Include="..\..\..\IceUtil\StringConverter.cpp" /> <ClCompile Include="..\..\..\IceUtil\StringUtil.cpp" /> + <ClCompile Include="..\..\StreamSocket.cpp" /> <ClCompile Include="..\..\Thread.cpp" /> <ClCompile Include="..\..\..\IceUtil\ThreadException.cpp" /> <ClCompile Include="..\..\..\IceUtil\Time.cpp" /> @@ -232,10 +233,10 @@ <ClCompile Include="..\..\UdpConnector.cpp" /> <ClCompile Include="..\..\UdpEndpointI.cpp" /> <ClCompile Include="..\..\UdpTransceiver.cpp" /> - <ClCompile Include="..\..\uwp\TcpAcceptor.cpp" /> - <ClCompile Include="..\..\uwp\TcpConnector.cpp" /> - <ClCompile Include="..\..\uwp\TcpEndpointI.cpp" /> - <ClCompile Include="..\..\uwp\TcpTransceiver.cpp" /> + <ClCompile Include="..\..\TcpAcceptor.cpp" /> + <ClCompile Include="..\..\TcpConnector.cpp" /> + <ClCompile Include="..\..\TcpEndpointI.cpp" /> + <ClCompile Include="..\..\TcpTransceiver.cpp" /> <ClCompile Include="..\..\Value.cpp" /> <ClCompile Include="..\..\ValueFactoryManagerI.cpp" /> <ClCompile Include="..\..\WSAcceptor.cpp" /> @@ -3566,4 +3567,4 @@ <Import Project="$(IceBuilderCppTargets)" Condition="Exists('$(IceBuilderCppTargets)')" /> <ImportGroup Label="ExtensionTargets"> </ImportGroup> -</Project> +</Project>
\ No newline at end of file diff --git a/cpp/src/Ice/msbuild/iceuwp++11/iceuwp++11.vcxproj.filters b/cpp/src/Ice/msbuild/iceuwp++11/iceuwp++11.vcxproj.filters index f6d97e7170b..4a33c8ded78 100644 --- a/cpp/src/Ice/msbuild/iceuwp++11/iceuwp++11.vcxproj.filters +++ b/cpp/src/Ice/msbuild/iceuwp++11/iceuwp++11.vcxproj.filters @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="utf-8"?> +<?xml version="1.0" encoding="utf-8"?> <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup> <Filter Include="Header Files"> @@ -319,18 +319,6 @@ <ClCompile Include="..\..\UdpTransceiver.cpp"> <Filter>Source Files</Filter> </ClCompile> - <ClCompile Include="..\..\uwp\TcpAcceptor.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\uwp\TcpConnector.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\uwp\TcpEndpointI.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\uwp\TcpTransceiver.cpp"> - <Filter>Source Files</Filter> - </ClCompile> <ClCompile Include="..\..\RegisterPluginsInit.cpp"> <Filter>Source Files</Filter> </ClCompile> @@ -1102,6 +1090,19 @@ <ClCompile Include="..\..\Timer.cpp"> <Filter>Source Files</Filter> </ClCompile> + <ClCompile Include="..\..\TcpEndpointI.cpp" /> + <ClCompile Include="..\..\TcpAcceptor.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\TcpConnector.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\TcpTransceiver.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\StreamSocket.cpp"> + <Filter>Source Files</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <IceBuilder Include="..\..\..\..\..\slice\Ice\BuiltinSequences.ice"> @@ -1926,4 +1927,4 @@ <Filter>Header Files\x64\Release</Filter> </ClInclude> </ItemGroup> -</Project> +</Project>
\ No newline at end of file diff --git a/cpp/src/Ice/uwp/RegisterPluginsInit.cpp b/cpp/src/Ice/uwp/RegisterPluginsInit.cpp deleted file mode 100644 index c8294ee7033..00000000000 --- a/cpp/src/Ice/uwp/RegisterPluginsInit.cpp +++ /dev/null @@ -1,46 +0,0 @@ -// ********************************************************************** -// -// Copyright (c) 2003-2016 ZeroC, Inc. All rights reserved. -// -// This copy of Ice is licensed to you under the terms described in the -// ICE_LICENSE file included in this distribution. -// -// ********************************************************************** - -#include <Ice/Initialize.h> -#include <Ice/RegisterPluginsInit.h> - -using namespace std; -using namespace Ice; -using namespace IceInternal; - -extern "C" -{ - -Plugin* createIceUDP(const CommunicatorPtr&, const string&, const StringSeq&); -Plugin* createIceTCP(const CommunicatorPtr&, const string&, const StringSeq&); -Plugin* createIceSSL(const CommunicatorPtr&, const string&, const StringSeq&); -Plugin* createIceDiscovery(const CommunicatorPtr&, const string&, const StringSeq&); -Plugin* createIceLocatorDiscovery(const CommunicatorPtr&, const string&, const StringSeq&); - -} - -namespace Ice -{ - -void -registerIceSSL(bool) -{ - // Nothing to do, IceSSL is always registered by the static initializer. -} - -} - -RegisterPluginsInit::RegisterPluginsInit() -{ - registerPluginFactory("IceUDP", createIceUDP, true); - registerPluginFactory("IceTCP", createIceTCP, true); - registerPluginFactory("IceSSL", createIceSSL, true); - registerPluginFactory("IceDiscovery", createIceDiscovery, false); - registerPluginFactory("IceLocatorDiscovery", createIceLocatorDiscovery, false); -} diff --git a/cpp/src/Ice/uwp/TcpAcceptor.cpp b/cpp/src/Ice/uwp/TcpAcceptor.cpp deleted file mode 100644 index f97aa28c434..00000000000 --- a/cpp/src/Ice/uwp/TcpAcceptor.cpp +++ /dev/null @@ -1,221 +0,0 @@ -// ********************************************************************** -// -// Copyright (c) 2003-2016 ZeroC, Inc. All rights reserved. -// -// This copy of Ice is licensed to you under the terms described in the -// ICE_LICENSE file included in this distribution. -// -// ********************************************************************** - -#include <Ice/uwp/TcpAcceptor.h> -#include <Ice/uwp/TcpTransceiver.h> -#include <Ice/uwp/TcpEndpointI.h> - -#include <Ice/ProtocolInstance.h> -#include <Ice/LocalException.h> -#include <Ice/LoggerUtil.h> -#include <Ice/Exception.h> -#include <Ice/Properties.h> -#include <IceUtil/StringUtil.h> - -using namespace std; -using namespace Ice; -using namespace IceInternal; - -using namespace Platform; -using namespace Windows::Foundation; -using namespace Windows::Storage::Streams; -using namespace Windows::Networking; -using namespace Windows::Networking::Sockets; - -IceUtil::Shared* IceInternal::upCast(TcpAcceptor* p) { return p; } - -NativeInfoPtr -IceInternal::TcpAcceptor::getNativeInfo() -{ - return this; -} - -void -IceInternal::TcpAcceptor::setCompletedHandler(SocketOperationCompletedHandler^ handler) -{ - _completedHandler = handler; -} - -void -IceInternal::TcpAcceptor::close() -{ - IceUtil::Mutex::Lock lock(_mutex); - if(_acceptPending) - { - assert(_accepted.empty()); - _completedHandler(SocketOperationRead); - _acceptPending = false; - } - else if(!_accepted.empty()) - { - for(deque<StreamSocket^>::const_iterator p = _accepted.begin(); p != _accepted.end(); ++p) - { - closeSocket(*p); - } - _accepted.clear(); - } - - if(_fd != INVALID_SOCKET) - { - closeSocketNoThrow(_fd); - _fd = INVALID_SOCKET; - } -} - -EndpointIPtr -IceInternal::TcpAcceptor::listen() -{ - try - { - const_cast<Address&>(_addr) = doBind(_fd, _addr); - } - catch(...) - { - _fd = INVALID_SOCKET; - throw; - } - _endpoint = _endpoint->endpoint(this); - return _endpoint; -} - -void -IceInternal::TcpAcceptor::startAccept() -{ - assert(_fd != INVALID_SOCKET); - - // - // If there are already sockets waiting to be accepted, we just - // notify the selector that the acceptor is ready for acceting the - // new socket. Otherwise, we set the _acceptPending flag, when a - // new socket connection event is received, the message handler - // will notify the selector. - // - IceUtil::Mutex::Lock lock(_mutex); - assert(!_acceptPending); - if(!_accepted.empty()) - { - _completedHandler(SocketOperationRead); - } - else - { - _acceptPending = true; - } -} - -void -IceInternal::TcpAcceptor::finishAccept() -{ - // - // Nothing to do, we just check there's at least one accepted - // socket or the acceptor was closed. - // - IceUtil::Mutex::Lock lock(_mutex); - assert(!_acceptPending && (!_accepted.empty() || _fd == INVALID_SOCKET)); -} - -TransceiverPtr -IceInternal::TcpAcceptor::accept() -{ - if(_fd == INVALID_SOCKET) // Acceptor closed. - { - assert(_accepted.empty()); - throw SocketException(__FILE__, __LINE__); - } - - StreamSocket^ fd; - { - IceUtil::Mutex::Lock lock(_mutex); - assert(!_accepted.empty()); - fd = _accepted.front(); - _accepted.pop_front(); - } - - return new TcpTransceiver(_instance, fd, true); -} - -string -IceInternal::TcpAcceptor::protocol() const -{ - return _instance->protocol(); -} - -string -IceInternal::TcpAcceptor::toString() const -{ - return addrToString(_addr); -} - -string -IceInternal::TcpAcceptor::toDetailedString() const -{ - ostringstream os; - os << "local address = " << toString(); - vector<string> intfs = getHostsForEndpointExpand(inetAddrToString(_addr), _instance->protocolSupport(), true); - if(!intfs.empty()) - { - os << "\nlocal interfaces = "; - os << IceUtilInternal::joinString(intfs, ", "); - } - return os.str(); -} - -int -IceInternal::TcpAcceptor::effectivePort() const -{ - return getPort(_addr); -} - -IceInternal::TcpAcceptor::TcpAcceptor(const TcpEndpointIPtr& endpoint, - const ProtocolInstancePtr& instance, - const string& host, - int port) : - _endpoint(endpoint), - _instance(instance), - _addr(getAddressForServer(host, port, _instance->protocolSupport(), instance->preferIPv6())), - _acceptPending(false) -{ - _fd = ref new StreamSocketListener(); - - safe_cast<StreamSocketListener^>(_fd)->ConnectionReceived += - ref new TypedEventHandler<StreamSocketListener^, StreamSocketListenerConnectionReceivedEventArgs^>( - [=](StreamSocketListener^, StreamSocketListenerConnectionReceivedEventArgs^ args) - { - queueAcceptedSocket(args->Socket); - }); -} - -IceInternal::TcpAcceptor::~TcpAcceptor() -{ - assert(_fd == INVALID_SOCKET); -} - -void -IceInternal::TcpAcceptor::queueAcceptedSocket(StreamSocket^ socket) -{ - IceUtil::Mutex::Lock lock(_mutex); - if(_fd == INVALID_SOCKET) // Acceptor was closed. - { - closeSocket(socket); - return; - } - _accepted.push_back(socket); - - // - // If the acceptor is waiting for a socket to be accepted, notify - // the selector that the acceptor is ready for "read". This will - // in turn caused finishAccept() and accept() to be called by the - // thread pool. If the acceptor isn't ready to accept the socket, - // it is just queued, when startAccept is called it will be dequed. - // - if(_acceptPending) - { - _completedHandler(SocketOperationRead); - _acceptPending = false; - } -} diff --git a/cpp/src/Ice/uwp/TcpAcceptor.h b/cpp/src/Ice/uwp/TcpAcceptor.h deleted file mode 100644 index bfef0da2712..00000000000 --- a/cpp/src/Ice/uwp/TcpAcceptor.h +++ /dev/null @@ -1,65 +0,0 @@ -// ********************************************************************** -// -// Copyright (c) 2003-2016 ZeroC, Inc. All rights reserved. -// -// This copy of Ice is licensed to you under the terms described in the -// ICE_LICENSE file included in this distribution. -// -// ********************************************************************** - -#ifndef ICE_UWP_TCP_ACCEPTOR_H -#define ICE_UWP_TCP_ACCEPTOR_H - -#include <Ice/TransceiverF.h> -#include <Ice/ProtocolInstanceF.h> -#include <Ice/Acceptor.h> -#include <Ice/Network.h> -#include <Ice/uwp/TransceiverF.h> - -#include <IceUtil/Mutex.h> - -#include <deque> - -namespace IceInternal -{ - -class TcpAcceptor : public Acceptor, public NativeInfo -{ -public: - - virtual NativeInfoPtr getNativeInfo(); - virtual void setCompletedHandler(SocketOperationCompletedHandler^); - - virtual void close(); - virtual EndpointIPtr listen(); - - virtual void startAccept(); - virtual void finishAccept(); - - virtual TransceiverPtr accept(); - virtual std::string protocol() const; - virtual std::string toString() const; - virtual std::string toDetailedString() const; - - int effectivePort() const; - -private: - - TcpAcceptor(const TcpEndpointIPtr&, const ProtocolInstancePtr&, const std::string&, int); - virtual ~TcpAcceptor(); - friend class TcpEndpointI; - - virtual void queueAcceptedSocket(Windows::Networking::Sockets::StreamSocket^); - - TcpEndpointIPtr _endpoint; - const ProtocolInstancePtr _instance; - const Address _addr; - - IceUtil::Mutex _mutex; - bool _acceptPending; - SocketOperationCompletedHandler^ _completedHandler; - std::deque<Windows::Networking::Sockets::StreamSocket^> _accepted; -}; - -} -#endif diff --git a/cpp/src/Ice/uwp/TcpConnector.cpp b/cpp/src/Ice/uwp/TcpConnector.cpp deleted file mode 100644 index cba0245497e..00000000000 --- a/cpp/src/Ice/uwp/TcpConnector.cpp +++ /dev/null @@ -1,126 +0,0 @@ -// ********************************************************************** -// -// Copyright (c) 2003-2016 ZeroC, Inc. All rights reserved. -// -// This copy of Ice is licensed to you under the terms described in the -// ICE_LICENSE file included in this distribution. -// -// ********************************************************************** - -#include <Ice/uwp/TcpConnector.h> -#include <Ice/uwp/TcpTransceiver.h> -#include <Ice/uwp/TcpEndpointI.h> - -#include <Ice/ProtocolInstance.h> -#include <Ice/LoggerUtil.h> -#include <Ice/Network.h> -#include <Ice/Exception.h> - -using namespace std; -using namespace Ice; -using namespace IceInternal; - -TransceiverPtr -IceInternal::TcpConnector::connect() -{ - TransceiverPtr transceiver = new TcpTransceiver(_instance, createSocket(false, _addr), false); - dynamic_cast<TcpTransceiver*>(transceiver.get())->connect(_addr); - return transceiver; -} - -Short -IceInternal::TcpConnector::type() const -{ - return _instance->type(); -} - -string -IceInternal::TcpConnector::toString() const -{ - return addrToString(_addr); -} - -bool -IceInternal::TcpConnector::operator==(const Connector& r) const -{ - const TcpConnector* p = dynamic_cast<const TcpConnector*>(&r); - if(!p) - { - return false; - } - - if(type() != p->type()) - { - return false; - } - - if(compareAddress(_addr, p->_addr) != 0) - { - return false; - } - - if(_timeout != p->_timeout) - { - return false; - } - - if(_connectionId != p->_connectionId) - { - return false; - } - - return true; -} - -bool -IceInternal::TcpConnector::operator!=(const Connector& r) const -{ - return !operator==(r); -} - -bool -IceInternal::TcpConnector::operator<(const Connector& r) const -{ - const TcpConnector* p = dynamic_cast<const TcpConnector*>(&r); - if(!p) - { - return type() < r.type(); - } - - if(type() < p->type()) - { - return true; - } - else if(p->type() < type()) - { - return false; - } - - if(_timeout < p->_timeout) - { - return true; - } - else if(p->_timeout < _timeout) - { - return false; - } - - if(_connectionId < p->_connectionId) - { - return true; - } - else if(p->_connectionId < _connectionId) - { - return false; - } - return compareAddress(_addr, p->_addr) < 0; -} - -IceInternal::TcpConnector::TcpConnector(const ProtocolInstancePtr& instance, const Address& addr, - Ice::Int timeout, const string& connectionId) : - _instance(instance), - _addr(addr), - _timeout(timeout), - _connectionId(connectionId) -{ -} diff --git a/cpp/src/Ice/uwp/TcpConnector.h b/cpp/src/Ice/uwp/TcpConnector.h deleted file mode 100644 index 96f005de7d0..00000000000 --- a/cpp/src/Ice/uwp/TcpConnector.h +++ /dev/null @@ -1,47 +0,0 @@ -// ********************************************************************** -// -// Copyright (c) 2003-2016 ZeroC, Inc. All rights reserved. -// -// This copy of Ice is licensed to you under the terms described in the -// ICE_LICENSE file included in this distribution. -// -// ********************************************************************** - -#ifndef ICE_UWP_TCP_CONNECTOR_H -#define ICE_UWP_TCP_CONNECTOR_H - -#include <Ice/TransceiverF.h> -#include <Ice/ProtocolInstanceF.h> -#include <Ice/Connector.h> -#include <Ice/Network.h> - -namespace IceInternal -{ - -class TcpConnector : public Connector -{ -public: - - virtual TransceiverPtr connect(); - - virtual Ice::Short type() const; - virtual std::string toString() const; - - virtual bool operator==(const Connector&) const; - virtual bool operator!=(const Connector&) const; - virtual bool operator<(const Connector&) const; - -private: - - TcpConnector(const ProtocolInstancePtr&, const Address&, Ice::Int, const std::string&); - friend class TcpEndpointI; - - const ProtocolInstancePtr _instance; - const Address _addr; - const Ice::Int _timeout; - const std::string _connectionId; -}; - -} - -#endif diff --git a/cpp/src/Ice/uwp/TcpEndpointI.cpp b/cpp/src/Ice/uwp/TcpEndpointI.cpp deleted file mode 100644 index 020d7283b6f..00000000000 --- a/cpp/src/Ice/uwp/TcpEndpointI.cpp +++ /dev/null @@ -1,426 +0,0 @@ -// ********************************************************************** -// -// Copyright (c) 2003-2016 ZeroC, Inc. All rights reserved. -// -// This copy of Ice is licensed to you under the terms described in the -// ICE_LICENSE file included in this distribution. -// -// ********************************************************************** - -#include <Ice/uwp/TcpEndpointI.h> -#include <Ice/uwp/TcpAcceptor.h> -#include <Ice/uwp/TcpConnector.h> -#include <Ice/uwp/TcpTransceiver.h> - -#include <Ice/Network.h> -#include <Ice/OutputStream.h> -#include <Ice/InputStream.h> -#include <Ice/LocalException.h> -#include <Ice/ProtocolInstance.h> -#include <Ice/DefaultsAndOverrides.h> -#include <Ice/HashUtil.h> - -using namespace std; -using namespace Ice; -using namespace IceInternal; - -extern "C" -{ - -Plugin* -createIceTCP(const CommunicatorPtr& com, const string&, const StringSeq&) -{ - ProtocolInstancePtr instance = new ProtocolInstance(com, TCPEndpointType, "tcp", false); - return new EndpointFactoryPlugin(com, new TcpEndpointFactory(instance)); -} - -} - -#ifndef ICE_CPP11_MAPPING -IceUtil::Shared* IceInternal::upCast(TcpEndpointI* p) { return p; } -#endif - -IceInternal::TcpEndpointI::TcpEndpointI(const ProtocolInstancePtr& instance, const string& ho, Int po, Int ti, - const string& conId, bool co) : - IPEndpointI(instance, ho, po, Address(), conId), - _timeout(ti), - _compress(co) -{ -} - -IceInternal::TcpEndpointI::TcpEndpointI(const ProtocolInstancePtr& instance) : - IPEndpointI(instance), - _timeout(-2), - _compress(false) -{ -} - -IceInternal::TcpEndpointI::TcpEndpointI(const ProtocolInstancePtr& instance, InputStream* s) : - IPEndpointI(instance, s), - _timeout(-1), - _compress(false) -{ - s->read(const_cast<Int&>(_timeout)); - s->read(const_cast<bool&>(_compress)); -} - -EndpointInfoPtr -IceInternal::TcpEndpointI::getInfo() const -{ - IPEndpointInfoPtr info; - info = ICE_MAKE_SHARED(InfoI<Ice::TCPEndpointInfo>, shared_from_this()); - fillEndpointInfo(info.get()); - return info; -} - -EndpointInfoPtr -IceInternal::TcpEndpointI::getWSInfo(const string& resource) const -{ - IPEndpointInfoPtr info; - Ice::WSEndpointInfoPtr i = ICE_MAKE_SHARED(InfoI<Ice::WSEndpointInfo>, shared_from_this()); - i->resource = resource; - info = i; - fillEndpointInfo(info.get()); - return info; -} - -Int -IceInternal::TcpEndpointI::timeout() const -{ - return _timeout; -} - -EndpointIPtr -IceInternal::TcpEndpointI::timeout(Int timeout) const -{ - if(timeout == _timeout) - { - return shared_from_this(); - } - else - { - return ICE_MAKE_SHARED(TcpEndpointI, _instance, _host, _port, timeout, _connectionId, _compress); - } -} - -EndpointIPtr -IceInternal::TcpEndpointI::connectionId(const string& connectionId) const -{ - if(connectionId == _connectionId) - { - return shared_from_this(); - } - else - { - return ICE_MAKE_SHARED(TcpEndpointI, _instance, _host, _port, _timeout, connectionId, _compress); - } -} - -bool -IceInternal::TcpEndpointI::compress() const -{ - return _compress; -} - -EndpointIPtr -IceInternal::TcpEndpointI::compress(bool compress) const -{ - if(compress == _compress) - { - return shared_from_this(); - } - else - { - return ICE_MAKE_SHARED(TcpEndpointI, _instance, _host, _port, _timeout, _connectionId, compress); - } -} - -bool -IceInternal::TcpEndpointI::datagram() const -{ - return false; -} - -bool -IceInternal::TcpEndpointI::secure() const -{ - return false; -} - -TransceiverPtr -IceInternal::TcpEndpointI::transceiver() const -{ - return 0; -} - -AcceptorPtr -IceInternal::TcpEndpointI::acceptor(const string&) const -{ - return new TcpAcceptor(ICE_DYNAMIC_CAST(TcpEndpointI, shared_from_this()), _instance, _host, _port); -} - -TcpEndpointIPtr -IceInternal::TcpEndpointI::endpoint(const TcpAcceptorPtr& acceptor) const -{ - return ICE_MAKE_SHARED(TcpEndpointI, _instance, _host, acceptor->effectivePort(), _timeout, _connectionId, _compress); -} - -string -IceInternal::TcpEndpointI::options() const -{ - // - // WARNING: Certain features, such as proxy validation in Glacier2, - // depend on the format of proxy strings. Changes to toString() and - // methods called to generate parts of the reference string could break - // these features. Please review for all features that depend on the - // format of proxyToString() before changing this and related code. - // - ostringstream s; - - s << IPEndpointI::options(); - - if(_timeout == -1) - { - s << " -t infinite"; - } - else - { - s << " -t " << _timeout; - } - - if(_compress) - { - s << " -z"; - } - - return s.str(); -} - -bool -#ifdef ICE_CPP11_MAPPING -IceInternal::TcpEndpointI::operator==(const Endpoint& r) const -#else -IceInternal::TcpEndpointI::operator==(const LocalObject& r) const -#endif -{ - if(!IPEndpointI::operator==(r)) - { - return false; - } - - const TcpEndpointI* p = dynamic_cast<const TcpEndpointI*>(&r); - if(!p) - { - return false; - } - - if(this == p) - { - return true; - } - - if(_timeout != p->_timeout) - { - return false; - } - - if(_compress != p->_compress) - { - return false; - } - - return true; -} - -bool -#ifdef ICE_CPP11_MAPPING -IceInternal::TcpEndpointI::operator<(const Endpoint& r) const -#else -IceInternal::TcpEndpointI::operator<(const LocalObject& r) const -#endif -{ - const TcpEndpointI* p = dynamic_cast<const TcpEndpointI*>(&r); - if(!p) - { - const EndpointI* e = dynamic_cast<const EndpointI*>(&r); - if(!e) - { - return false; - } - return type() < e->type(); - } - - if(this == p) - { - return false; - } - - if(_timeout < p->_timeout) - { - return true; - } - else if(p->_timeout < _timeout) - { - return false; - } - - if(!_compress && p->_compress) - { - return true; - } - else if(p->_compress < _compress) - { - return false; - } - - return IPEndpointI::operator<(r); -} - -void -IceInternal::TcpEndpointI::streamWriteImpl(OutputStream* s) const -{ - IPEndpointI::streamWriteImpl(s); - s->write(_timeout); - s->write(_compress); -} - -void -IceInternal::TcpEndpointI::hashInit(Ice::Int& h) const -{ - IPEndpointI::hashInit(h); - hashAdd(h, _timeout); - hashAdd(h, _compress); -} - -void -IceInternal::TcpEndpointI::fillEndpointInfo(IPEndpointInfo* info) const -{ - IPEndpointI::fillEndpointInfo(info); - info->timeout = _timeout; - info->compress = _compress; -} - -void -IceInternal::TcpEndpointI::initWithOptions(vector<string>& args, bool oaEndpoint) -{ - IPEndpointI::initWithOptions(args, oaEndpoint); - - if(_timeout == -2) - { - const_cast<Int&>(_timeout) = _instance->defaultTimeout(); - } -} - -bool -IceInternal::TcpEndpointI::checkOption(const string& option, const string& argument, const string& endpoint) -{ - if(IPEndpointI::checkOption(option, argument, endpoint)) - { - return true; - } - - switch(option[1]) - { - case 't': - { - if(argument.empty()) - { - EndpointParseException ex(__FILE__, __LINE__); - ex.str = "no argument provided for -t option in endpoint " + endpoint; - throw ex; - } - - if(argument == "infinite") - { - const_cast<Int&>(_timeout) = -1; - } - else - { - istringstream t(argument); - if(!(t >> const_cast<Int&>(_timeout)) || !t.eof() || _timeout < 1) - { - EndpointParseException ex(__FILE__, __LINE__); - ex.str = "invalid timeout value `" + argument + "' in endpoint " + endpoint; - throw ex; - } - } - return true; - } - - case 'z': - { - if(!argument.empty()) - { - EndpointParseException ex(__FILE__, __LINE__); - ex.str = "unexpected argument `" + argument + "' provided for -z option in " + endpoint; - throw ex; - } - const_cast<bool&>(_compress) = true; - return true; - } - - default: - { - return false; - } - } -} - -ConnectorPtr -IceInternal::TcpEndpointI::createConnector(const Address& address, const NetworkProxyPtr& proxy) const -{ - // TODO: Add support for network proxies? - return new TcpConnector(_instance, address, _timeout, _connectionId); -} - -IPEndpointIPtr -IceInternal::TcpEndpointI::createEndpoint(const string& host, int port, const string& connectionId) const -{ - return ICE_MAKE_SHARED(TcpEndpointI, _instance, host, port, _timeout, connectionId, _compress); -} - -IceInternal::TcpEndpointFactory::TcpEndpointFactory(const ProtocolInstancePtr& instance) : _instance(instance) -{ -} - -IceInternal::TcpEndpointFactory::~TcpEndpointFactory() -{ -} - -Short -IceInternal::TcpEndpointFactory::type() const -{ - return _instance->type(); -} - -string -IceInternal::TcpEndpointFactory::protocol() const -{ - return _instance->protocol(); -} - -EndpointIPtr -IceInternal::TcpEndpointFactory::create(vector<string>& args, bool oaEndpoint) const -{ - IPEndpointIPtr endpt = ICE_MAKE_SHARED(TcpEndpointI, _instance); - endpt->initWithOptions(args, oaEndpoint); - return endpt; -} - -EndpointIPtr -IceInternal::TcpEndpointFactory::read(InputStream* s) const -{ - return ICE_MAKE_SHARED(TcpEndpointI, _instance, s); -} - -void -IceInternal::TcpEndpointFactory::destroy() -{ - _instance = 0; -} - -EndpointFactoryPtr -IceInternal::TcpEndpointFactory::clone(const ProtocolInstancePtr& instance) const -{ - return new TcpEndpointFactory(instance); -} diff --git a/cpp/src/Ice/uwp/TcpEndpointI.h b/cpp/src/Ice/uwp/TcpEndpointI.h deleted file mode 100644 index 19a40eac4e5..00000000000 --- a/cpp/src/Ice/uwp/TcpEndpointI.h +++ /dev/null @@ -1,100 +0,0 @@ -// ********************************************************************** -// -// Copyright (c) 2003-2016 ZeroC, Inc. All rights reserved. -// -// This copy of Ice is licensed to you under the terms described in the -// ICE_LICENSE file included in this distribution. -// -// ********************************************************************** - -#ifndef ICE_UWP_TCP_ENDPOINT_I_H -#define ICE_UWP_TCP_ENDPOINT_I_H - -#include <IceUtil/Config.h> -#include <Ice/IPEndpointI.h> -#include <Ice/EndpointFactory.h> -#include <Ice/WSEndpoint.h> -#include <Ice/Network.h> // for IceIternal::Address -#include <Ice/uwp/TransceiverF.h> - -namespace IceInternal -{ - -class TcpEndpointI : public IPEndpointI, public WSEndpointDelegate -{ -public: - - TcpEndpointI(const ProtocolInstancePtr&, const std::string&, Ice::Int, Ice::Int, const std::string&, bool); - TcpEndpointI(const ProtocolInstancePtr&); - TcpEndpointI(const ProtocolInstancePtr&, Ice::InputStream*); - - virtual Ice::EndpointInfoPtr getInfo() const; - virtual Ice::EndpointInfoPtr getWSInfo(const std::string&) const; - - virtual Ice::Int timeout() const; - virtual EndpointIPtr timeout(Ice::Int) const; - virtual EndpointIPtr connectionId(const ::std::string&) const; - virtual bool compress() const; - virtual EndpointIPtr compress(bool) const; - virtual bool datagram() const; - virtual bool secure() const; - - virtual TransceiverPtr transceiver() const; - virtual AcceptorPtr acceptor(const std::string&) const; - virtual std::string options() const; - -#ifdef ICE_CPP11_MAPPING - virtual bool operator==(const Ice::Endpoint&) const; - virtual bool operator<(const Ice::Endpoint&) const; -#else - virtual bool operator==(const Ice::LocalObject&) const; - virtual bool operator<(const Ice::LocalObject&) const; -#endif - - TcpEndpointIPtr endpoint(const TcpAcceptorPtr&) const; - - using IPEndpointI::connectionId; - -protected: - - virtual void streamWriteImpl(Ice::OutputStream*) const; - virtual void hashInit(Ice::Int&) const; - virtual void initWithOptions(std::vector<std::string>&, bool); - virtual void fillEndpointInfo(Ice::IPEndpointInfo*) const; - virtual bool checkOption(const std::string&, const std::string&, const std::string&); - - virtual ConnectorPtr createConnector(const Address&, const NetworkProxyPtr&) const; - virtual IPEndpointIPtr createEndpoint(const std::string&, int, const std::string&) const; - -private: - - // - // All members are const, because endpoints are immutable. - // - const Ice::Int _timeout; - const bool _compress; -}; - -class TcpEndpointFactory : public EndpointFactory -{ -public: - - TcpEndpointFactory(const ProtocolInstancePtr&); - virtual ~TcpEndpointFactory(); - - virtual Ice::Short type() const; - virtual std::string protocol() const; - virtual EndpointIPtr create(std::vector<std::string>&, bool) const; - virtual EndpointIPtr read(Ice::InputStream*) const; - virtual void destroy(); - - virtual EndpointFactoryPtr clone(const ProtocolInstancePtr&) const; - -private: - - ProtocolInstancePtr _instance; -}; - -} - -#endif diff --git a/cpp/src/Ice/uwp/TcpTransceiver.cpp b/cpp/src/Ice/uwp/TcpTransceiver.cpp deleted file mode 100644 index de400168fa3..00000000000 --- a/cpp/src/Ice/uwp/TcpTransceiver.cpp +++ /dev/null @@ -1,399 +0,0 @@ -// ********************************************************************** -// -// Copyright (c) 2003-2016 ZeroC, Inc. All rights reserved. -// -// This copy of Ice is licensed to you under the terms described in the -// ICE_LICENSE file included in this distribution. -// -// ********************************************************************** - -#include <Ice/uwp/TcpTransceiver.h> -#include <Ice/Connection.h> -#include <Ice/ProtocolInstance.h> -#include <Ice/LoggerUtil.h> -#include <Ice/Buffer.h> -#include <Ice/LocalException.h> -#include <Ice/Properties.h> - -using namespace std; -using namespace Ice; -using namespace IceInternal; - -using namespace Platform; -using namespace Windows::Foundation; -using namespace Windows::Storage::Streams; -using namespace Windows::Networking; -using namespace Windows::Networking::Sockets; - -namespace -{ - -AsyncOperationCompletedHandler<unsigned int>^ -createAsyncOperationCompletedHandler(SocketOperationCompletedHandler^ cb, SocketOperation op, AsyncInfo& info) -{ - return ref new AsyncOperationCompletedHandler<unsigned int>( - [=,&info] (IAsyncOperation<unsigned int>^ operation, Windows::Foundation::AsyncStatus status) - { - if(status != Windows::Foundation::AsyncStatus::Completed) - { - info.count = SOCKET_ERROR; - info.error = operation->ErrorCode.Value; - } - else - { - info.count = static_cast<int>(operation->GetResults()); - } - cb(op); - }); -} - -} - -NativeInfoPtr -IceInternal::TcpTransceiver::getNativeInfo() -{ - return this; -} - -void -IceInternal::TcpTransceiver::setCompletedHandler(SocketOperationCompletedHandler^ handler) -{ - _completedHandler = handler; - _readOperationCompletedHandler = createAsyncOperationCompletedHandler(handler, SocketOperationRead, _read); - _writeOperationCompletedHandler = createAsyncOperationCompletedHandler(handler, SocketOperationWrite, _write); -} - -SocketOperation -IceInternal::TcpTransceiver::initialize(Buffer&, Buffer&) -{ - if(_state == StateNeedConnect) - { - _state = StateConnectPending; - return SocketOperationConnect; - } - else if(_state <= StateConnectPending) - { - if(_write.count == SOCKET_ERROR) - { - checkConnectErrorCode(__FILE__, __LINE__, _write.error, _connectAddr.host); - } - _state = StateConnected; - _desc = fdToString(_fd); - } - assert(_state == StateConnected); - return SocketOperationNone; -} - -SocketOperation -#ifdef ICE_CPP11_MAPPING -IceInternal::TcpTransceiver::closing(bool initiator, exception_ptr) -#else -IceInternal::TcpTransceiver::closing(bool initiator, const Ice::LocalException&) -#endif -{ - // If we are initiating the connection closure, wait for the peer - // to close the TCP/IP connection. Otherwise, close immediately. - return initiator ? SocketOperationRead : SocketOperationNone; -} - -void -IceInternal::TcpTransceiver::close() -{ - assert(_fd != INVALID_SOCKET); - - _completedHandler = nullptr; - _readOperationCompletedHandler = nullptr; - _writeOperationCompletedHandler = nullptr; - - try - { - closeSocket(_fd); - _fd = INVALID_SOCKET; - } - catch(const SocketException&) - { - _fd = INVALID_SOCKET; - throw; - } -} - -SocketOperation -IceInternal::TcpTransceiver::write(Buffer& buf) -{ - return buf.i == buf.b.end() ? SocketOperationNone : SocketOperationWrite; -} - -SocketOperation -IceInternal::TcpTransceiver::read(Buffer& buf) -{ - return buf.i == buf.b.end() ? SocketOperationNone : SocketOperationRead; -} - -bool -IceInternal::TcpTransceiver::startWrite(Buffer& buf) -{ - if(_state < StateConnected) - { - try - { - IAsyncAction^ action = safe_cast<StreamSocket^>(_fd)->ConnectAsync( - _connectAddr.host, - _connectAddr.port, - SocketProtectionLevel::PlainSocket); - - if(!checkIfErrorOrCompleted(SocketOperationConnect, action)) - { - SocketOperationCompletedHandler^ completed = _completedHandler; - action->Completed = ref new AsyncActionCompletedHandler( - [=] (IAsyncAction^ info, Windows::Foundation::AsyncStatus status) - { - if(status != Windows::Foundation::AsyncStatus::Completed) - { - _write.count = SOCKET_ERROR; - _write.error = info->ErrorCode.Value; - } - else - { - _write.count = 0; - } - completed(SocketOperationConnect); - }); - } - } - catch(Platform::Exception^ ex) - { - checkConnectErrorCode(__FILE__, __LINE__, ex->HResult, _connectAddr.host); - } - return false; - } - - assert(!buf.b.empty()); - assert(buf.i != buf.b.end()); - - int packetSize = static_cast<int>(buf.b.end() - buf.i); - if(_maxSendPacketSize > 0 && packetSize > _maxSendPacketSize) - { - packetSize = _maxSendPacketSize; - } - assert(packetSize > 0); - _writer->WriteBytes(ref new Array<unsigned char>(&*buf.i, packetSize)); - try - { - DataWriterStoreOperation^ operation = _writer->StoreAsync(); - if(checkIfErrorOrCompleted(SocketOperationWrite, operation)) - { - _write.count = operation->GetResults(); - } - else - { - operation->Completed = _writeOperationCompletedHandler; - } - } - catch(Platform::Exception^ ex) - { - checkErrorCode(__FILE__, __LINE__, ex->HResult); - } - return packetSize == static_cast<int>(buf.b.end() - buf.i); -} - -void -IceInternal::TcpTransceiver::finishWrite(Buffer& buf) -{ - if(_state < StateConnected) - { - if(_write.count == SOCKET_ERROR) - { - checkConnectErrorCode(__FILE__, __LINE__, _write.error, _connectAddr.host); - } - _verified = true; - return; - } - - if(_write.count == SOCKET_ERROR) - { - checkErrorCode(__FILE__, __LINE__, _write.error); - } - - buf.i += _write.count; -} - -void -IceInternal::TcpTransceiver::startRead(Buffer& buf) -{ - int packetSize = static_cast<int>(buf.b.end() - buf.i); - if(_maxReceivePacketSize > 0 && packetSize > _maxReceivePacketSize) - { - packetSize = _maxReceivePacketSize; - } - assert(!buf.b.empty() && buf.i != buf.b.end()); - - try - { - DataReaderLoadOperation^ operation = _reader->LoadAsync(packetSize); - if(checkIfErrorOrCompleted(SocketOperationRead, operation)) - { - _read.count = operation->GetResults(); - } - else - { - operation->Completed = _readOperationCompletedHandler; - } - } - catch(Platform::Exception^ ex) - { - checkErrorCode(__FILE__, __LINE__, ex->HResult); - } -} - -void -IceInternal::TcpTransceiver::finishRead(Buffer& buf) -{ - if(_read.count == SOCKET_ERROR) - { - checkErrorCode(__FILE__, __LINE__, _read.error); - } - else if(_read.count == 0) - { - ConnectionLostException ex(__FILE__, __LINE__); - ex.error = 0; - throw ex; - } - - try - { - auto data = ref new Platform::Array<unsigned char>(_read.count); - _reader->ReadBytes(data); - memcpy(&*buf.i, data->Data, _read.count); - } - catch(Platform::Exception^ ex) - { - checkErrorCode(__FILE__, __LINE__, ex->HResult); - } - - buf.i += _read.count; -} - -string -IceInternal::TcpTransceiver::protocol() const -{ - return _instance->protocol(); -} - -string -IceInternal::TcpTransceiver::toString() const -{ - return _desc; -} - -string -IceInternal::TcpTransceiver::toDetailedString() const -{ - return toString(); -} - -Ice::ConnectionInfoPtr -IceInternal::TcpTransceiver::getInfo() const -{ - Ice::IPConnectionInfoPtr info; - info = ICE_MAKE_SHARED(Ice::TCPConnectionInfo); - fillConnectionInfo(info); - return info; -} - -Ice::ConnectionInfoPtr -IceInternal::TcpTransceiver::getWSInfo(const Ice::HeaderDict& headers) const -{ - Ice::WSConnectionInfoPtr info = ICE_MAKE_SHARED(Ice::WSConnectionInfo); - fillConnectionInfo(info); - info->headers = headers; - return info; -} - -void -IceInternal::TcpTransceiver::checkSendSize(const Buffer&) -{ -} - - void - IceInternal::TcpTransceiver::setBufferSize(int rcvSize, int sndSize) - { - setTcpBufSize(_fd, rcvSize, sndSize, _instance); - } - -IceInternal::TcpTransceiver::TcpTransceiver(const ProtocolInstancePtr& instance, SOCKET fd, bool connected) : - NativeInfo(fd), - _instance(instance), - _state(connected ? StateConnected : StateNeedConnect), - _desc(connected ? fdToString(_fd) : string()), - _verified(false) -{ - StreamSocket^ streamSocket = safe_cast<StreamSocket^>(_fd); - _writer = ref new DataWriter(streamSocket->OutputStream); - _reader = ref new DataReader(streamSocket->InputStream); - _reader->InputStreamOptions = InputStreamOptions::Partial; - - setTcpBufSize(_fd, _instance); - - _maxSendPacketSize = streamSocket->Control->OutboundBufferSizeInBytes / 2; - if(_maxSendPacketSize < 512) - { - _maxSendPacketSize = 0; - } - - _maxReceivePacketSize = instance->properties()->getPropertyAsIntWithDefault("Ice.TCP.RcvSize", 128 * 1024); -} - -IceInternal::TcpTransceiver::~TcpTransceiver() -{ - assert(_fd == INVALID_SOCKET); -} - -void -IceInternal::TcpTransceiver::connect(const Address& addr) -{ - _connectAddr = addr; -} - -bool -IceInternal::TcpTransceiver::checkIfErrorOrCompleted(SocketOperation op, IAsyncInfo^ info, int count) -{ - // - // NOTE: It's important to only check for info->Status once as it - // might change during the checks below (the Status can be changed - // by the Windows thread pool concurrently). - // - // We consider that a canceled async status is the same as an - // error. A canceled async status can occur if there's a timeout - // and the socket is closed. - // - Windows::Foundation::AsyncStatus status = info->Status; - if(status == Windows::Foundation::AsyncStatus::Completed) - { - _completedHandler(op); - return true; - } - else if (status == Windows::Foundation::AsyncStatus::Started) - { - return false; - } - else - { - if(_state < StateConnected) - { - checkConnectErrorCode(__FILE__, __LINE__, info->ErrorCode.Value, _connectAddr.host); - } - else - { - checkErrorCode(__FILE__, __LINE__, info->ErrorCode.Value); - } - return true; // Prevent compiler warning. - } -} - -void -IceInternal::TcpTransceiver::fillConnectionInfo(const Ice::IPConnectionInfoPtr& info) const -{ - fdToAddressAndPort(_fd, info->localAddress, info->localPort, info->remoteAddress, info->remotePort); - info->rcvSize = getRecvBufferSize(_fd); - info->sndSize = getSendBufferSize(_fd); -} diff --git a/cpp/src/Ice/uwp/TcpTransceiver.h b/cpp/src/Ice/uwp/TcpTransceiver.h deleted file mode 100644 index 433da311100..00000000000 --- a/cpp/src/Ice/uwp/TcpTransceiver.h +++ /dev/null @@ -1,94 +0,0 @@ -// ********************************************************************** -// -// Copyright (c) 2003-2016 ZeroC, Inc. All rights reserved. -// -// This copy of Ice is licensed to you under the terms described in the -// ICE_LICENSE file included in this distribution. -// -// ********************************************************************** - -#ifndef ICE_UWP_TCP_TRANSCEIVER_H -#define ICE_UWP_TCP_TRANSCEIVER_H - -#include <Ice/ProtocolInstanceF.h> -#include <Ice/Transceiver.h> -#include <Ice/Network.h> -#include <Ice/WSTransceiver.h> - -namespace IceInternal -{ - -class StreamConnector; -class StreamAcceptor; - -class TcpTransceiver : public Transceiver, public NativeInfo, public WSTransceiverDelegate -{ - enum State - { - StateNeedConnect, - StateConnectPending, - StateConnected - }; - -public: - - virtual NativeInfoPtr getNativeInfo(); - virtual void setCompletedHandler(SocketOperationCompletedHandler^); - - virtual SocketOperation initialize(Buffer&, Buffer&); -#ifdef ICE_CPP11_MAPPING - virtual SocketOperation closing(bool, std::exception_ptr); -#else - virtual SocketOperation closing(bool, const Ice::LocalException&); -#endif - virtual void close(); - virtual SocketOperation write(Buffer&); - virtual SocketOperation read(Buffer&); - - virtual bool startWrite(Buffer&); - virtual void finishWrite(Buffer&); - virtual void startRead(Buffer&); - virtual void finishRead(Buffer&); - - virtual std::string protocol() const; - virtual std::string toString() const; - virtual std::string toDetailedString() const; - virtual Ice::ConnectionInfoPtr getInfo() const; - virtual Ice::ConnectionInfoPtr getWSInfo(const Ice::HeaderDict&) const; - virtual void checkSendSize(const Buffer&); - virtual void setBufferSize(int rcvSize, int sndSize); - -private: - - TcpTransceiver(const ProtocolInstancePtr&, SOCKET, bool); - virtual ~TcpTransceiver(); - - void connect(const Address&); - bool checkIfErrorOrCompleted(SocketOperation, Windows::Foundation::IAsyncInfo^, int = 0); - void fillConnectionInfo(const Ice::IPConnectionInfoPtr&) const; - - friend class TcpConnector; - friend class TcpAcceptor; - - const ProtocolInstancePtr _instance; - - State _state; - std::string _desc; - bool _verified; - Address _connectAddr; - - AsyncInfo _read; - AsyncInfo _write; - int _maxSendPacketSize; - int _maxReceivePacketSize; - - Windows::Storage::Streams::DataReader^ _reader; - Windows::Storage::Streams::DataWriter^ _writer; - - Windows::Foundation::AsyncOperationCompletedHandler<unsigned int>^ _readOperationCompletedHandler; - Windows::Foundation::AsyncOperationCompletedHandler<unsigned int>^ _writeOperationCompletedHandler; -}; - -} - -#endif diff --git a/cpp/src/Ice/uwp/TransceiverF.h b/cpp/src/Ice/uwp/TransceiverF.h deleted file mode 100644 index 76572a71a66..00000000000 --- a/cpp/src/Ice/uwp/TransceiverF.h +++ /dev/null @@ -1,31 +0,0 @@ -// ********************************************************************** -// -// Copyright (c) 2003-2016 ZeroC, Inc. All rights reserved. -// -// This copy of Ice is licensed to you under the terms described in the -// ICE_LICENSE file included in this distribution. -// -// ********************************************************************** - -#ifndef ICE_UWP_TRANSCEIVER_F_H -#define ICE_UWP_TRANSCEIVER_F_H - -#include <IceUtil/Shared.h> -#include <Ice/Handle.h> - -namespace IceInternal -{ - -class TcpEndpointI; -#ifndef ICE_CPP11_MAPPING -ICE_API IceUtil::Shared* upCast(TcpEndpointI*); -#endif -ICE_DEFINE_PTR(TcpEndpointIPtr, TcpEndpointI); - -class TcpAcceptor; -ICE_API IceUtil::Shared* upCast(TcpAcceptor*); -typedef IceInternal::Handle<TcpAcceptor> TcpAcceptorPtr; - -} - -#endif diff --git a/cpp/src/IceBT/EndpointI.cpp b/cpp/src/IceBT/EndpointI.cpp index 1f4ab9a99da..5c0d31cc8ef 100644 --- a/cpp/src/IceBT/EndpointI.cpp +++ b/cpp/src/IceBT/EndpointI.cpp @@ -92,17 +92,15 @@ IceBT::EndpointI::EndpointI(const InstancePtr& instance, InputStream* s) : } void -IceBT::EndpointI::streamWrite(OutputStream* s) const +IceBT::EndpointI::streamWriteImpl(OutputStream* s) const { // // _name and _channel are not marshaled. // - s->startEncapsulation(); s->write(_addr, false); s->write(_uuid, false); s->write(_timeout); s->write(_compress); - s->endEncapsulation(); } Ice::Short @@ -758,7 +756,8 @@ IceBT::EndpointFactoryI::destroy() } IceInternal::EndpointFactoryPtr -IceBT::EndpointFactoryI::clone(const IceInternal::ProtocolInstancePtr& instance) const +IceBT::EndpointFactoryI::clone(const IceInternal::ProtocolInstancePtr& instance, + const IceInternal::EndpointFactoryPtr&) const { return new EndpointFactoryI(new Instance(_instance->engine(), instance->type(), instance->protocol())); } diff --git a/cpp/src/IceBT/EndpointI.h b/cpp/src/IceBT/EndpointI.h index d3034413567..f0d2433d122 100644 --- a/cpp/src/IceBT/EndpointI.h +++ b/cpp/src/IceBT/EndpointI.h @@ -30,7 +30,7 @@ public: EndpointI(const InstancePtr&); EndpointI(const InstancePtr&, Ice::InputStream*); - virtual void streamWrite(Ice::OutputStream*) const; + virtual void streamWriteImpl(Ice::OutputStream*) const; virtual Ice::Short type() const; virtual const std::string& protocol() const; virtual Ice::Int timeout() const; @@ -49,7 +49,7 @@ public: #ifdef ICE_CPP11_MAPPING virtual bool operator==(const Ice::Endpoint&) const; - virtual bool operator<(const Ice::Endpoint&) const; + virtual bool operator<(const Ice::Endpoint&) const; #else virtual bool operator==(const Ice::LocalObject&) const; virtual bool operator<(const Ice::LocalObject&) const; @@ -140,7 +140,8 @@ public: virtual IceInternal::EndpointIPtr read(Ice::InputStream*) const; virtual void destroy(); - virtual IceInternal::EndpointFactoryPtr clone(const IceInternal::ProtocolInstancePtr&) const; + virtual IceInternal::EndpointFactoryPtr clone(const IceInternal::ProtocolInstancePtr&, + const IceInternal::EndpointFactoryPtr&) const; private: diff --git a/cpp/src/IceBT/PluginI.cpp b/cpp/src/IceBT/PluginI.cpp index 07a6fb67c42..c8f2882bbfb 100644 --- a/cpp/src/IceBT/PluginI.cpp +++ b/cpp/src/IceBT/PluginI.cpp @@ -59,13 +59,21 @@ registerIceBT(bool loadOnInitialize) IceBT::PluginI::PluginI(const Ice::CommunicatorPtr& com) : _engine(new Engine(com)) { + IceInternal::ProtocolPluginFacadePtr pluginFacade = IceInternal::getProtocolPluginFacade(com); + // // Register the endpoint factory. We have to do this now, rather // than in initialize, because the communicator may need to // interpret proxies before the plug-in is fully initialized. // - IceInternal::EndpointFactoryPtr btFactory = new EndpointFactoryI(new Instance(_engine, EndpointType, "bt")); - IceInternal::getProtocolPluginFacade(com)->addEndpointFactory(btFactory); + pluginFacade->addEndpointFactory(new EndpointFactoryI(new Instance(_engine, BTEndpointType, "bt"))); + + IceInternal::EndpointFactoryPtr sslFactory = pluginFacade->getEndpointFactory(SSLEndpointType); + if(sslFactory) + { + InstancePtr instance = new Instance(_engine, BTSEndpointType, "bts"); + pluginFacade->addEndpointFactory(sslFactory->clone(instance, new EndpointFactoryI(instance))); + } } void diff --git a/cpp/src/IceBT/StreamSocket.cpp b/cpp/src/IceBT/StreamSocket.cpp index 7c398fbed6f..ba4b27ca57f 100644 --- a/cpp/src/IceBT/StreamSocket.cpp +++ b/cpp/src/IceBT/StreamSocket.cpp @@ -104,12 +104,12 @@ IceBT::StreamSocket::setBufferSize(int rcvSize, int sndSize) // Warn if the size that was set is less than the requested size and // we have not already warned. // - IceInternal::BufSizeWarnInfo winfo = _instance->getBufSizeWarn(EndpointType); + IceInternal::BufSizeWarnInfo winfo = _instance->getBufSizeWarn(BTEndpointType); if(!winfo.rcvWarn || rcvSize != winfo.rcvSize) { Ice::Warning out(_instance->logger()); out << "BT receive buffer size: requested size of " << rcvSize << " adjusted to " << size; - _instance->setRcvBufSizeWarn(EndpointType, rcvSize); + _instance->setRcvBufSizeWarn(BTEndpointType, rcvSize); } } } @@ -127,12 +127,12 @@ IceBT::StreamSocket::setBufferSize(int rcvSize, int sndSize) { // Warn if the size that was set is less than the requested size and // we have not already warned. - IceInternal::BufSizeWarnInfo winfo = _instance->getBufSizeWarn(EndpointType); + IceInternal::BufSizeWarnInfo winfo = _instance->getBufSizeWarn(BTEndpointType); if(!winfo.sndWarn || sndSize != winfo.sndSize) { Ice::Warning out(_instance->logger()); out << "BT send buffer size: requested size of " << sndSize << " adjusted to " << size; - _instance->setSndBufSizeWarn(EndpointType, sndSize); + _instance->setSndBufSizeWarn(BTEndpointType, sndSize); } } } diff --git a/cpp/src/IceBT/TransceiverI.cpp b/cpp/src/IceBT/TransceiverI.cpp index fc4c878f35a..4a3f4005803 100644 --- a/cpp/src/IceBT/TransceiverI.cpp +++ b/cpp/src/IceBT/TransceiverI.cpp @@ -90,6 +90,11 @@ IceBT::TransceiverI::getInfo() const IceBT::ConnectionInfoPtr info = ICE_MAKE_SHARED(IceBT::ConnectionInfo); fdToAddressAndChannel(_stream->fd(), info->localAddress, info->localChannel, info->remoteAddress, info->remoteChannel); + if(_stream->fd() != INVALID_SOCKET) + { + info->rcvSize = IceInternal::getRecvBufferSize(_stream->fd()); + info->sndSize = IceInternal::getSendBufferSize(_stream->fd()); + } info->uuid = _uuid; return info; } diff --git a/cpp/src/IceDiscovery/PluginI.cpp b/cpp/src/IceDiscovery/PluginI.cpp index 5360dc14d31..615e0eeec96 100644 --- a/cpp/src/IceDiscovery/PluginI.cpp +++ b/cpp/src/IceDiscovery/PluginI.cpp @@ -28,17 +28,12 @@ using namespace IceDiscovery; // // Plugin factory function. // -extern "C" -{ - -ICE_DISCOVERY_API Ice::Plugin* +extern "C" ICE_DISCOVERY_API Ice::Plugin* createIceDiscovery(const Ice::CommunicatorPtr& communicator, const string&, const Ice::StringSeq&) { return new PluginI(communicator); } -} - namespace Ice { @@ -50,6 +45,15 @@ registerIceDiscovery(bool loadOnInitialize) } +// +// Objective-C function to allow Objective-C programs to register plugin. +// +extern "C" ICE_DISCOVERY_API void +ICEregisterIceDiscovery(bool loadOnInitialize) +{ + Ice::registerIceDiscovery(loadOnInitialize); +} + PluginI::PluginI(const Ice::CommunicatorPtr& communicator) : _communicator(communicator) { } diff --git a/cpp/src/IceGrid/RegistryI.cpp b/cpp/src/IceGrid/RegistryI.cpp index fb31d8d588b..d246b26dd9c 100644 --- a/cpp/src/IceGrid/RegistryI.cpp +++ b/cpp/src/IceGrid/RegistryI.cpp @@ -118,6 +118,19 @@ private: ProcessPtr _origProcess; }; +Ice::IPConnectionInfoPtr +getIPConnectionInfo(const Ice::ConnectionInfoPtr& info) +{ + for(Ice::ConnectionInfoPtr p = info; p; p = p->underlying) + { + Ice::IPConnectionInfoPtr ipInfo = Ice::IPConnectionInfoPtr::dynamicCast(p); + if(ipInfo) + { + return ipInfo; + } + } + return ICE_NULLPTR; +} ProcessI::ProcessI(const RegistryIPtr& registry, const ProcessPtr& origProcess) : _registry(registry), @@ -1338,10 +1351,11 @@ RegistryI::getSSLInfo(const ConnectionPtr& connection, string& userDN) throw exc; } - sslinfo.remotePort = info->remotePort; - sslinfo.remoteHost = info->remoteAddress; - sslinfo.localPort = info->localPort; - sslinfo.localHost = info->localAddress; + Ice::IPConnectionInfoPtr ipInfo = getIPConnectionInfo(info); + sslinfo.remotePort = ipInfo->remotePort; + sslinfo.remoteHost = ipInfo->remoteAddress; + sslinfo.localPort = ipInfo->localPort; + sslinfo.localHost = ipInfo->localAddress; sslinfo.cipher = info->cipher; sslinfo.certs = info->certs; if(info->certs.size() > 0) diff --git a/cpp/src/Ice/ios/iAPConnector.h b/cpp/src/IceIAP/Connector.h index f2bd4281d95..f2bd4281d95 100644 --- a/cpp/src/Ice/ios/iAPConnector.h +++ b/cpp/src/IceIAP/Connector.h diff --git a/cpp/src/Ice/ios/iAPConnector.mm b/cpp/src/IceIAP/Connector.mm index 935858b9c6f..b7c57ddb31b 100644 --- a/cpp/src/Ice/ios/iAPConnector.mm +++ b/cpp/src/IceIAP/Connector.mm @@ -7,9 +7,9 @@ // // ********************************************************************** -#include "iAPTransceiver.h" -#include "iAPEndpointI.h" -#include "iAPConnector.h" +#include "Transceiver.h" +#include "EndpointI.h" +#include "Connector.h" #include <Ice/ProtocolInstance.h> #include <Ice/Exception.h> diff --git a/cpp/src/Ice/ios/iAPEndpointI.h b/cpp/src/IceIAP/EndpointI.h index dc85e085bf7..c4016073453 100644 --- a/cpp/src/Ice/ios/iAPEndpointI.h +++ b/cpp/src/IceIAP/EndpointI.h @@ -33,7 +33,7 @@ public: iAPEndpointI(const IceInternal::ProtocolInstancePtr&); iAPEndpointI(const IceInternal::ProtocolInstancePtr&, Ice::InputStream*); - virtual void streamWrite(Ice::OutputStream*) const; + virtual void streamWriteImpl(Ice::OutputStream*) const; virtual Ice::EndpointInfoPtr getInfo() const; virtual Ice::Short type() const; @@ -97,7 +97,8 @@ public: virtual IceInternal::EndpointIPtr read(Ice::InputStream*) const; virtual void destroy(); - virtual IceInternal::EndpointFactoryPtr clone(const IceInternal::ProtocolInstancePtr&) const; + virtual IceInternal::EndpointFactoryPtr clone(const IceInternal::ProtocolInstancePtr&, + const IceInternal::EndpointFactoryPtr&) const; private: diff --git a/cpp/src/Ice/ios/iAPEndpointI.mm b/cpp/src/IceIAP/EndpointI.mm index 86ca8060fbc..44a0526d9ab 100644 --- a/cpp/src/Ice/ios/iAPEndpointI.mm +++ b/cpp/src/IceIAP/EndpointI.mm @@ -7,8 +7,10 @@ // // ********************************************************************** -#include "iAPEndpointI.h" -#include "iAPConnector.h" +#include "EndpointI.h" +#include "Connector.h" + +#include <IceIAP/EndpointInfo.h> #include <Ice/Network.h> #include <Ice/InputStream.h> @@ -20,6 +22,8 @@ #include <Ice/EndpointFactoryManager.h> #include <Ice/Properties.h> #include <Ice/HashUtil.h> +#include <Ice/ProtocolPluginFacade.h> +#include <Ice/RegisterPlugins.h> #include <CoreFoundation/CoreFoundation.h> @@ -29,18 +33,62 @@ using namespace std; using namespace Ice; using namespace IceInternal; -extern "C" +namespace +{ + +class iAPEndpointFactoryPlugin : public Ice::Plugin { +public: + + iAPEndpointFactoryPlugin(const Ice::CommunicatorPtr& com) + { + ProtocolPluginFacadePtr pluginFacade = getProtocolPluginFacade(com); + + // iAP transport + ProtocolInstancePtr instance = new ProtocolInstance(com, iAPEndpointType, "iap", false); + pluginFacade->addEndpointFactory(new IceObjC::iAPEndpointFactory(instance)); + + // SSL based on iAP transport + EndpointFactoryPtr ssl = pluginFacade->getEndpointFactory(SSLEndpointType); + if(ssl) + { + ProtocolInstancePtr sslinstance = new ProtocolInstance(com, iAPSEndpointType, "iaps", true); + pluginFacade->addEndpointFactory(ssl->clone(sslinstance, new IceObjC::iAPEndpointFactory(sslinstance))); + } + } -Plugin* + virtual void initialize() {} + virtual void destroy() {} +}; + +} + +extern "C" ICE_IAP_API Plugin* createIceIAP(const CommunicatorPtr& com, const string&, const StringSeq&) { - ProtocolInstancePtr instance = new ProtocolInstance(com, iAPEndpointType, "iap", false); - return new EndpointFactoryPlugin(com, new IceObjC::iAPEndpointFactory(instance)); + return new iAPEndpointFactoryPlugin(com); +} + +namespace Ice +{ + +ICE_IAP_API void +registerIceIAP(bool loadOnInitialize) +{ + Ice::registerPluginFactory("IceIAP", createIceIAP, loadOnInitialize); } } +// +// Objective-C function to allow Objective-C programs to register plugin. +// +extern "C" ICE_IAP_API void +ICEregisterIceIAP(bool loadOnInitialize) +{ + Ice::registerIceIAP(loadOnInitialize); +} + IceObjC::iAPEndpointI::iAPEndpointI(const ProtocolInstancePtr& instance, const string& m, const string& o, const string& n, const string& p, Int ti, const string& conId, bool co) : @@ -70,26 +118,33 @@ IceObjC::iAPEndpointI::iAPEndpointI(const ProtocolInstancePtr& instance, InputSt s->read(const_cast<string&>(_manufacturer), false); s->read(const_cast<string&>(_modelNumber), false); s->read(const_cast<string&>(_name), false); + s->read(const_cast<string&>(_protocol), false); s->read(const_cast<Int&>(_timeout)); s->read(const_cast<bool&>(_compress)); } void -IceObjC::iAPEndpointI::streamWrite(OutputStream* s) const +IceObjC::iAPEndpointI::streamWriteImpl(OutputStream* s) const { - s->startEncapsulation(); s->write(_manufacturer, false); s->write(_modelNumber, false); s->write(_name, false); + s->write(_protocol, false); s->write(_timeout); s->write(_compress); - s->endEncapsulation(); } EndpointInfoPtr IceObjC::iAPEndpointI::getInfo() const { - return 0; + IceIAP::EndpointInfoPtr info = ICE_MAKE_SHARED(InfoI<IceIAP::EndpointInfo>, shared_from_this()); + info->timeout = _timeout; + info->compress = _compress; + info->manufacturer = _manufacturer; + info->modelNumber = _modelNumber; + info->name = _name; + info->protocol = _protocol; + return info; } Short @@ -131,7 +186,8 @@ IceObjC::iAPEndpointI::timeout(Int t) const } else { - return ICE_MAKE_SHARED(iAPEndpointI, _instance, _manufacturer, _modelNumber, _name, _protocol, t, _connectionId, _compress); + return ICE_MAKE_SHARED(iAPEndpointI, _instance, _manufacturer, _modelNumber, _name, _protocol, t, _connectionId, + _compress); } } @@ -150,7 +206,8 @@ IceObjC::iAPEndpointI::connectionId(const string& cId) const } else { - return ICE_MAKE_SHARED(iAPEndpointI, _instance, _manufacturer, _modelNumber, _name, _protocol, _timeout, cId, _compress); + return ICE_MAKE_SHARED(iAPEndpointI, _instance, _manufacturer, _modelNumber, _name, _protocol, _timeout, cId, + _compress); } } @@ -169,7 +226,8 @@ IceObjC::iAPEndpointI::compress(bool c) const } else { - return ICE_MAKE_SHARED(iAPEndpointI, _instance, _manufacturer, _modelNumber, _name, _protocol, _timeout, _connectionId, c); + return ICE_MAKE_SHARED(iAPEndpointI, _instance, _manufacturer, _modelNumber, _name, _protocol, _timeout, + _connectionId, c); } } @@ -197,37 +255,28 @@ IceObjC::iAPEndpointI::connectors_async(Ice::EndpointSelectionType selType, NSArray* array = [manager connectedAccessories]; NSEnumerator* enumerator = [array objectEnumerator]; EAAccessory* accessory = nil; - int lastError = 0; while((accessory = [enumerator nextObject])) { if(!accessory.connected) { - lastError = 1; continue; } - if(!_manufacturer.empty() && _manufacturer != [accessory.manufacturer UTF8String]) { - lastError = 2; continue; } if(!_modelNumber.empty() && _modelNumber != [accessory.modelNumber UTF8String]) { - lastError = 3; continue; } if(!_name.empty() && _name != [accessory.name UTF8String]) { - lastError = 4; continue; } - if(![accessory.protocolStrings containsObject:protocol]) { - lastError = 5; continue; } - c.push_back(new iAPConnector(_instance, _timeout, _connectionId, protocol, accessory)); } [protocol release]; @@ -268,7 +317,8 @@ IceObjC::iAPEndpointI::equivalent(const EndpointIPtr& endpoint) const } return endpointI->_manufacturer == _manufacturer && endpointI->_modelNumber == _modelNumber && - endpointI->_name == _name; + endpointI->_name == _name && + endpointI->_protocol == _protocol; } bool @@ -304,6 +354,11 @@ IceObjC::iAPEndpointI::operator==(const Ice::LocalObject& r) const return false; } + if(_protocol != p->_protocol) + { + return false; + } + if(_timeout != p->_timeout) { return false; @@ -372,6 +427,15 @@ IceObjC::iAPEndpointI::operator<(const Ice::LocalObject& r) const return false; } + if(_protocol < p->_protocol) + { + return true; + } + else if(p->_protocol < _protocol) + { + return false; + } + if(_timeout < p->_timeout) { return true; @@ -477,6 +541,7 @@ IceObjC::iAPEndpointI::options() const { s << " -t " << _timeout; } + if(_compress) { s << " -z"; @@ -491,6 +556,7 @@ IceObjC::iAPEndpointI::hash() const hashAdd(h, _manufacturer); hashAdd(h, _modelNumber); hashAdd(h, _name); + hashAdd(h, _protocol); hashAdd(h, _timeout); hashAdd(h, _connectionId); return h; @@ -634,7 +700,7 @@ IceObjC::iAPEndpointFactory::destroy() } EndpointFactoryPtr -IceObjC::iAPEndpointFactory::clone(const ProtocolInstancePtr& instance) const +IceObjC::iAPEndpointFactory::clone(const ProtocolInstancePtr& instance, const IceInternal::EndpointFactoryPtr&) const { return new iAPEndpointFactory(instance); } diff --git a/cpp/src/IceIAP/Makefile.mk b/cpp/src/IceIAP/Makefile.mk new file mode 100644 index 00000000000..daeffbead19 --- /dev/null +++ b/cpp/src/IceIAP/Makefile.mk @@ -0,0 +1,20 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2016 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +$(project)_libraries = IceIAP + +IceIAP_configs := xcodesdk cpp11-xcodesdk +IceIAP_platforms := iphoneos iphonesimulator + +IceIAP_targetdir := $(libdir) +IceIAP_dependencies := Ice +IceIAP_sliceflags := --include-dir IceIAP --dll-export ICE_IAP_API +IceIAP_cppflags := -DICE_IAP_API_EXPORTS + +projects += $(project) diff --git a/cpp/src/Ice/ios/iAPTransceiver.h b/cpp/src/IceIAP/Transceiver.h index 6aaeb731241..b82ed27c395 100644 --- a/cpp/src/Ice/ios/iAPTransceiver.h +++ b/cpp/src/IceIAP/Transceiver.h @@ -66,6 +66,7 @@ private: void checkError(NSError*, const char*, int); IceInternal::ProtocolInstancePtr _instance; + EASession* _session; NSInputStream* _readStream; NSOutputStream* _writeStream; iAPTransceiverCallback* _callback; diff --git a/cpp/src/Ice/ios/iAPTransceiver.mm b/cpp/src/IceIAP/Transceiver.mm index 3139b8f608e..a9a57dbf407 100644 --- a/cpp/src/Ice/ios/iAPTransceiver.mm +++ b/cpp/src/IceIAP/Transceiver.mm @@ -7,8 +7,10 @@ // // ********************************************************************** -#include "iAPTransceiver.h" -#include "iAPEndpointI.h" +#include "Transceiver.h" +#include "EndpointI.h" + +#include <IceIAP/ConnectionInfo.h> #include <Ice/LocalException.h> #include <Ice/ProtocolInstance.h> @@ -62,8 +64,7 @@ using namespace IceInternal; callback->readyCallback(static_cast<SocketOperation>(SocketOperationConnect | SocketOperationWrite)); } break; - case NSStreamEventEndEncountered: - case NSStreamEventErrorOccurred: + default: if([[stream class] isSubclassOfClass:[NSInputStream class]]) { callback->readyCallback(SocketOperationRead, -1); // Error @@ -88,7 +89,6 @@ SocketOperation IceObjC::iAPTransceiver::registerWithRunLoop(SocketOperation op) { IceUtil::Mutex::Lock sync(_mutex); - SocketOperation readyOp = SocketOperationNone; if(op & SocketOperationConnect) { @@ -236,39 +236,16 @@ IceObjC::iAPTransceiver::initialize(Buffer& readBuffer, Buffer& writeBuffer) { if(_error) { - assert([_writeStream streamStatus] == NSStreamStatusError); - NSError* err = [_writeStream streamError]; - NSString* domain = [err domain]; - if([domain compare:NSPOSIXErrorDomain] == NSOrderedSame) + NSError* err = nil; + if([_writeStream streamStatus] == NSStreamStatusError) { - errno = [err code]; - [err release]; - if(connectionRefused()) - { - ConnectionRefusedException ex(__FILE__, __LINE__); - ex.error = getSocketErrno(); - throw ex; - } - else if(connectFailed()) - { - ConnectFailedException ex(__FILE__, __LINE__); - ex.error = getSocketErrno(); - throw ex; - } - else - { - SocketException ex(__FILE__, __LINE__); - ex.error = getSocketErrno(); - throw ex; - } + err = [_writeStream streamError]; } - - // Otherwise throw a generic exception. - CFNetworkException ex(__FILE__, __LINE__); - ex.domain = [domain UTF8String]; - ex.error = [err code]; - [err release]; - throw ex; + if([_readStream streamStatus] == NSStreamStatusError) + { + err = [_readStream streamError]; + } + checkError(err, __FILE__, __LINE__); } _state = StateConnected; } @@ -296,7 +273,7 @@ IceObjC::iAPTransceiver::close() SocketOperation IceObjC::iAPTransceiver::write(Buffer& buf) { - IceUtil::Mutex::Lock sync(_mutex); + IceUtil::Mutex::Lock sync(_mutex); if(_error) { assert([_writeStream streamStatus] == NSStreamStatusError); @@ -421,7 +398,14 @@ IceObjC::iAPTransceiver::toDetailedString() const Ice::ConnectionInfoPtr IceObjC::iAPTransceiver::getInfo() const { - return 0; + IceIAP::ConnectionInfoPtr info = new IceIAP::ConnectionInfo(); + info->manufacturer = [_session.accessory.manufacturer UTF8String]; + info->name = [_session.accessory.name UTF8String]; + info->modelNumber = [_session.accessory.modelNumber UTF8String]; + info->firmwareRevision = [_session.accessory.firmwareRevision UTF8String]; + info->hardwareRevision = [_session.accessory.hardwareRevision UTF8String]; + info->protocol = [_session.protocolString UTF8String]; + return info; } void @@ -437,20 +421,23 @@ IceObjC::iAPTransceiver::setBufferSize(int, int) IceObjC::iAPTransceiver::iAPTransceiver(const ProtocolInstancePtr& instance, EASession* session) : StreamNativeInfo(INVALID_SOCKET), _instance(instance), - _readStream([[session inputStream] retain]), - _writeStream([[session outputStream] retain]), + _session([session retain]), + _readStream([session inputStream]), + _writeStream([session outputStream]), _readStreamRegistered(false), _writeStreamRegistered(false), _error(false), _state(StateNeedConnect) { - _desc = string("name = ") + [session.accessory.name UTF8String]; + ostringstream os; + os << "name = " << [session.accessory.name UTF8String] << "\n"; + os << "protocol = " << [session.protocolString UTF8String]; + _desc = os.str(); } IceObjC::iAPTransceiver::~iAPTransceiver() { - [_readStream release]; - [_writeStream release]; + [_session release]; } void diff --git a/cpp/src/IceLocatorDiscovery/PluginI.cpp b/cpp/src/IceLocatorDiscovery/PluginI.cpp index 4851e98bfcc..ee1e79d9c99 100644 --- a/cpp/src/IceLocatorDiscovery/PluginI.cpp +++ b/cpp/src/IceLocatorDiscovery/PluginI.cpp @@ -27,17 +27,12 @@ using namespace IceLocatorDiscovery; // // Plugin factory function. // -extern "C" -{ - -ICE_LOCATOR_DISCOVERY_API Ice::Plugin* +extern "C" ICE_LOCATOR_DISCOVERY_API Ice::Plugin* createIceLocatorDiscovery(const Ice::CommunicatorPtr& communicator, const string&, const Ice::StringSeq&) { return new PluginI(communicator); } -} - namespace Ice { @@ -49,6 +44,15 @@ registerIceLocatorDiscovery(bool loadOnInitialize) } +// +// Objective-C function to allow Objective-C programs to register plugin. +// +extern "C" ICE_LOCATOR_DISCOVERY_API void +ICEregisterIceLocatorDiscovery(bool loadOnInitialize) +{ + Ice::registerIceLocatorDiscovery(loadOnInitialize); +} + namespace { diff --git a/cpp/src/IcePatch2/Server.cpp b/cpp/src/IcePatch2/Server.cpp index f0d0dc21b32..b559a091796 100644 --- a/cpp/src/IcePatch2/Server.cpp +++ b/cpp/src/IcePatch2/Server.cpp @@ -53,7 +53,7 @@ IcePatch2::PatcherService::start(int argc, char* argv[], int& status) IceUtilInternal::Options opts; opts.addOpt("h", "help"); opts.addOpt("v", "version"); - + vector<string> args; try { @@ -109,7 +109,7 @@ IcePatch2::PatcherService::start(int argc, char* argv[], int& status) { throw "cannot get the current directory:\n" + IceUtilInternal::lastErrorToString(); } - + dataDir = cwd + '/' + dataDir; } @@ -125,7 +125,7 @@ IcePatch2::PatcherService::start(int argc, char* argv[], int& status) error(ex); return false; } - + const string endpointsProperty = "IcePatch2.Endpoints"; string endpoints = properties->getProperty(endpointsProperty); if(endpoints.empty()) diff --git a/cpp/src/IceSSL/AcceptorI.cpp b/cpp/src/IceSSL/AcceptorI.cpp index 7f8c70341ed..8042fb8d195 100644 --- a/cpp/src/IceSSL/AcceptorI.cpp +++ b/cpp/src/IceSSL/AcceptorI.cpp @@ -11,23 +11,15 @@ #include <IceSSL/EndpointI.h> #include <IceSSL/Instance.h> + #include <IceSSL/OpenSSLTransceiverI.h> #include <IceSSL/SecureTransportTransceiverI.h> #include <IceSSL/SChannelTransceiverI.h> +#include <IceSSL/WinRTTransceiverI.h> #include <IceSSL/Util.h> -#include <Ice/Communicator.h> -#include <Ice/Exception.h> #include <Ice/LocalException.h> -#include <Ice/LoggerUtil.h> -#include <Ice/Properties.h> -#include <Ice/StreamSocket.h> -#include <IceUtil/StringUtil.h> - -#ifdef ICE_USE_IOCP -# include <Mswsock.h> -#endif using namespace std; using namespace Ice; @@ -38,90 +30,43 @@ IceUtil::Shared* IceSSL::upCast(AcceptorI* p) { return p; } IceInternal::NativeInfoPtr IceSSL::AcceptorI::getNativeInfo() { - return this; + return _delegate->getNativeInfo(); } -#ifdef ICE_USE_IOCP +#if defined(ICE_USE_IOCP) || defined(ICE_OS_WINRT) IceInternal::AsyncInfo* -IceSSL::AcceptorI::getAsyncInfo(IceInternal::SocketOperation) +IceSSL::AcceptorI::getAsyncInfo(IceInternal::SocketOperation status) { - return &_info; + return _delegate->getNativeInfo()->getAsyncInfo(status); } #endif void IceSSL::AcceptorI::close() { - if(_fd != INVALID_SOCKET) - { - IceInternal::closeSocketNoThrow(_fd); - _fd = INVALID_SOCKET; - } + _delegate->close(); } IceInternal::EndpointIPtr IceSSL::AcceptorI::listen() { - try - { - const_cast<IceInternal::Address&>(_addr) = IceInternal::doBind(_fd, _addr); - IceInternal::doListen(_fd, _backlog); - } - catch(...) - { - _fd = INVALID_SOCKET; - throw; - } - _endpoint = _endpoint->endpoint(this); + _endpoint = _endpoint->endpoint(_delegate->listen()); return _endpoint; } -#ifdef ICE_USE_IOCP +#if defined(ICE_USE_IOCP) || defined(ICE_OS_WINRT) void IceSSL::AcceptorI::startAccept() { - LPFN_ACCEPTEX AcceptEx = NULL; // a pointer to the 'AcceptEx()' function - GUID GuidAcceptEx = WSAID_ACCEPTEX; // The Guid - DWORD dwBytes; - if(WSAIoctl(_fd, - SIO_GET_EXTENSION_FUNCTION_POINTER, - &GuidAcceptEx, - sizeof(GuidAcceptEx), - &AcceptEx, - sizeof(AcceptEx), - &dwBytes, - NULL, - NULL) == SOCKET_ERROR) - { - SocketException ex(__FILE__, __LINE__); - ex.error = IceInternal::getSocketErrno(); - throw ex; - } + _delegate->startAccept(); - assert(_acceptFd == INVALID_SOCKET); - _acceptFd = IceInternal::createSocket(false, _addr); - const int sz = static_cast<int>(_acceptBuf.size() / 2); - if(!AcceptEx(_fd, _acceptFd, &_acceptBuf[0], 0, sz, sz, &_info.count, &_info)) - { - if(!IceInternal::wouldBlock()) - { - SocketException ex(__FILE__, __LINE__); - ex.error = IceInternal::getSocketErrno(); - throw ex; - } - } } void IceSSL::AcceptorI::finishAccept() { - if(static_cast<int>(_info.count) == SOCKET_ERROR || _fd == INVALID_SOCKET) - { - IceInternal::closeSocketNoThrow(_acceptFd); - _acceptFd = INVALID_SOCKET; - _acceptError = _info.error; - } + _delegate->finishAccept(); } #endif @@ -138,121 +83,36 @@ IceSSL::AcceptorI::accept() throw ex; } -#ifndef ICE_USE_IOCP - SOCKET fd = IceInternal::doAccept(_fd); -#else - if(_acceptFd == INVALID_SOCKET) - { - SocketException ex(__FILE__, __LINE__); - ex.error = _acceptError; - throw ex; - } - - if(setsockopt(_acceptFd, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, (char*)&_acceptFd, sizeof(_acceptFd)) == - SOCKET_ERROR) - { - IceInternal::closeSocketNoThrow(_acceptFd); - _acceptFd = INVALID_SOCKET; - SocketException ex(__FILE__, __LINE__); - ex.error = IceInternal::getSocketErrno(); - throw ex; - } - - SOCKET fd = _acceptFd; - _acceptFd = INVALID_SOCKET; -#endif - - // - // SSL handshaking is performed in TransceiverI::initialize, since - // accept must not block. - // - return new TransceiverI(_instance, new IceInternal::StreamSocket(_instance, fd), _adapterName, true); + return new TransceiverI(_instance, _delegate->accept(), _adapterName, true); } string IceSSL::AcceptorI::protocol() const { - return _instance->protocol(); + return _delegate->protocol(); } string IceSSL::AcceptorI::toString() const { - return IceInternal::addrToString(_addr); + return _delegate->toString(); } string IceSSL::AcceptorI::toDetailedString() const { - ostringstream os; - os << "local address = " << toString(); - vector<string> intfs = getHostsForEndpointExpand(inetAddrToString(_addr), _instance->protocolSupport(), true); - if(!intfs.empty()) - { - os << "\nlocal interfaces = "; - os << IceUtilInternal::joinString(intfs, ", "); - } - return os.str(); + return _delegate->toDetailedString(); } -int -IceSSL::AcceptorI::effectivePort() const -{ - if(_addr.saStorage.ss_family == AF_INET) - { - return ntohs(_addr.saIn.sin_port); - } - else - { - return ntohs(_addr.saIn6.sin6_port); - } -} - -IceSSL::AcceptorI::AcceptorI(const EndpointIPtr& endpoint, const InstancePtr& instance, const string& adapterName, - const string& host, int port) : +IceSSL::AcceptorI::AcceptorI(const EndpointIPtr& endpoint, const InstancePtr& instance, + const IceInternal::AcceptorPtr& del, const string& adapterName) : _endpoint(endpoint), _instance(instance), - _adapterName(adapterName), - _addr(IceInternal::getAddressForServer(host, port, instance->protocolSupport(), instance->preferIPv6())) -#ifdef ICE_USE_IOCP - , _acceptFd(INVALID_SOCKET), - _info(IceInternal::SocketOperationRead) -#endif + _delegate(del), + _adapterName(adapterName) { -#ifdef SOMAXCONN - _backlog = instance->properties()->getPropertyAsIntWithDefault("Ice.TCP.Backlog", SOMAXCONN); -#else - _backlog = instance->properties()->getPropertyAsIntWithDefault("Ice.TCP.Backlog", 511); -#endif - - IceInternal::ProtocolSupport protocol = instance->protocolSupport(); - _fd = IceInternal::createServerSocket(false, _addr, protocol); -#ifdef ICE_USE_IOCP - _acceptBuf.resize((sizeof(sockaddr_storage) + 16) * 2); -#endif - IceInternal::setBlock(_fd, false); - IceInternal::setTcpBufSize(_fd, _instance); -#ifndef _WIN32 - // - // Enable SO_REUSEADDR on Unix platforms to allow re-using the - // socket even if it's in the TIME_WAIT state. On Windows, - // this doesn't appear to be necessary and enabling - // SO_REUSEADDR would actually not be a good thing since it - // allows a second process to bind to an address even it's - // already bound by another process. - // - // TODO: using SO_EXCLUSIVEADDRUSE on Windows would probably - // be better but it's only supported by recent Windows - // versions (XP SP2, Windows Server 2003). - // - IceInternal::setReuseAddress(_fd, true); -#endif } IceSSL::AcceptorI::~AcceptorI() { - assert(_fd == INVALID_SOCKET); -#ifdef ICE_USE_IOCP - assert(_acceptFd == INVALID_SOCKET); -#endif } diff --git a/cpp/src/IceSSL/AcceptorI.h b/cpp/src/IceSSL/AcceptorI.h index 465878a24c2..3ee5d5d2d4c 100644 --- a/cpp/src/IceSSL/AcceptorI.h +++ b/cpp/src/IceSSL/AcceptorI.h @@ -25,13 +25,13 @@ class AcceptorI : public IceInternal::Acceptor, public IceInternal::NativeInfo public: virtual IceInternal::NativeInfoPtr getNativeInfo(); -#ifdef ICE_USE_IOCP +#if defined(ICE_USE_IOCP) || defined(ICE_OS_WINRT) virtual IceInternal::AsyncInfo* getAsyncInfo(IceInternal::SocketOperation); #endif virtual void close(); virtual IceInternal::EndpointIPtr listen(); -#ifdef ICE_USE_IOCP +#if defined(ICE_USE_IOCP) || defined(ICE_OS_WINRT) virtual void startAccept(); virtual void finishAccept(); #endif @@ -40,25 +40,16 @@ public: virtual std::string toString() const; virtual std::string toDetailedString() const; - int effectivePort() const; - private: - AcceptorI(const EndpointIPtr&, const InstancePtr&, const std::string&, const std::string&, int); + AcceptorI(const EndpointIPtr&, const InstancePtr&, const IceInternal::AcceptorPtr&, const std::string&); virtual ~AcceptorI(); friend class EndpointI; EndpointIPtr _endpoint; const InstancePtr _instance; + const IceInternal::AcceptorPtr _delegate; const std::string _adapterName; - const IceInternal::Address _addr; - int _backlog; -#ifdef ICE_USE_IOCP - SOCKET _acceptFd; - int _acceptError; - std::vector<char> _acceptBuf; - IceInternal::AsyncInfo _info; -#endif }; } diff --git a/cpp/src/IceSSL/Certificate.cpp b/cpp/src/IceSSL/Certificate.cpp index 61597bdd0fe..5429a96b2e9 100644..100755 --- a/cpp/src/IceSSL/Certificate.cpp +++ b/cpp/src/IceSSL/Certificate.cpp @@ -15,6 +15,7 @@ #include <IceSSL/Util.h> #include <IceSSL/RFC2253.h> #include <Ice/Object.h> +#include <Ice/Base64.h> #if defined(ICE_USE_OPENSSL) # include <openssl/x509v3.h> @@ -42,12 +43,12 @@ extern "C" typedef void (*FreeFunc)(void*); #endif - using namespace std; using namespace Ice; using namespace IceSSL; #if defined(ICE_USE_SECURE_TRANSPORT) || defined(ICE_USE_SCHANNEL) + // // Map a certificate OID to its alias // @@ -80,7 +81,6 @@ const int certificateOIDSSize = sizeof(certificateOIDS) / sizeof(CertificateOID) #endif - #if defined(ICE_USE_SECURE_TRANSPORT) string @@ -98,29 +98,6 @@ certificateOIDAlias(const string& name) return name; } -// -// Map alternative name alias to its types. -// -const char* certificateAlternativeNameTypes[] = {"", "Email Address", "DNS Name", "", "Directory Name", "", "URI", - "IP Address"}; -const int certificateAlternativeNameTypesSize = sizeof(certificateAlternativeNameTypes) / sizeof(char*); - -int -certificateAlternativeNameType(const string& alias) -{ - if(!alias.empty()) - { - for(int i = 0; i < certificateAlternativeNameTypesSize; ++i) - { - if(alias == certificateAlternativeNameTypes[i]) - { - return i; - } - } - } - return -1; // Not supported -} - string escapeX509Name(const string& name) { @@ -149,6 +126,31 @@ escapeX509Name(const string& name) return os.str(); } +#if !defined(ICE_USE_SECURE_TRANSPORT_IOS) + +// +// Map alternative name alias to its types. +// +const char* certificateAlternativeNameTypes[] = {"", "Email Address", "DNS Name", "", "Directory Name", "", "URI", + "IP Address"}; +const int certificateAlternativeNameTypesSize = sizeof(certificateAlternativeNameTypes) / sizeof(char*); + +int +certificateAlternativeNameType(const string& alias) +{ + if(!alias.empty()) + { + for(int i = 0; i < certificateAlternativeNameTypesSize; ++i) + { + if(alias == certificateAlternativeNameTypes[i]) + { + return i; + } + } + } + return -1; // Not supported +} + DistinguishedName getX509Name(SecCertificateRef cert, CFTypeRef key) { @@ -256,8 +258,158 @@ getX509String(SecCertificateRef cert, CFTypeRef key) return value; } -#elif defined(ICE_USE_SCHANNEL) +#else // IOS + +// +// ASN1Parser to pase the subject/issuer ASN.1 DER encoded attributes on iOS. +// +class ASN1Parser +{ +public: + + ASN1Parser(CFDataRef data) : _data(CFDataGetBytePtr(data)), _length(CFDataGetLength(data)), _p(_data), _next(0) + { + } + + list<pair<string, string> > + parse() + { + list<pair<string, string> > rdns; + while(_p < _data + _length) + { + switch(parseByte()) + { + case 0x06: // OID + { + _rdn.first = parseOID(); + break; + } + case 0x12: // NumericString + case 0x13: // PrintableString + case 0x0C: // UTF8String + case 0x16: // IA5String + { + _rdn.second = escapeX509Name(parseUTF8String()); + break; + } + case 0x30: // SEQUENCE + case 0x31: // SET + { + int length = parseLength(0); + _next = _p + length; + if(_next > _data + _length) + { + throw CertificateEncodingException(__FILE__, __LINE__, "invalid length"); + } + break; + } + default: + { + // Unsupported tag, skip the SET. + if(!_next) + { + return rdns; + } + _p = _next; + _next = 0; + break; + } + } + if(_p == _next) + { + rdns.push_back(_rdn); + } + } + return rdns; + } + + string + parseOID() + { + int length = parseLength(1); + ostringstream oid; + unsigned char c = parseByte(); + oid << c / 40 << "." << c % 40; + while(--length > 0) + { + if((*_p & 0x80) == 0) + { + oid << "." << static_cast<int>(parseByte()); + } + else + { + uint64_t result = (uint64_t)(*_p & 127); + while(parseByte() & 128) + { + result = (result << 7) | (uint64_t)(*_p & 127); + --length; + } + oid << "." << result; + } + } + return certificateOIDAlias(oid.str()); + } + + string + parseUTF8String() + { + int length = parseLength(0); + string v(reinterpret_cast<const char*>(_p), length); + _p += length; + return v; + } + int + parseLength(int required) + { + int length = 0; + if((*_p & 0x80) == 0) + { + length = static_cast<int>(parseByte()); + } + else + { + int nbytes = static_cast<int>(parseByte()); + for(int i = 0; i < nbytes; ++i) + { + length = length * 256 + parseByte(); + } + } + if((required > 0 && length < required) || (_p + length > _data + _length)) + { + throw CertificateEncodingException(__FILE__, __LINE__, "invalid length"); + } + return length; + } + + unsigned char + parseByte() + { + if(_p >= _data + _length) + { + throw CertificateEncodingException(__FILE__, __LINE__, "invalid length"); + } + unsigned char b = *_p++; + return b; + } + +private: + + const unsigned char* _data; + const size_t _length; + const unsigned char* _p; + const unsigned char* _next; + pair<string, string> _rdn; + list<pair<string, string> > _rdns; +}; +#endif + +#elif defined(ICE_USE_SCHANNEL) || defined(ICE_OS_WINRT) + +const Ice::Long TICKS_PER_MSECOND = 10000LL; +const Ice::Long MSECS_TO_EPOCH = 11644473600000LL; + +#if defined(ICE_USE_SCHANNEL) void loadCertificate(PCERT_SIGNED_CONTENT_INFO* cert, const char* buffer, DWORD length) { @@ -294,9 +446,6 @@ loadCertificate(PCERT_SIGNED_CONTENT_INFO* cert, const string& file) loadCertificate(cert, &buffer[0], static_cast<DWORD>(buffer.size())); } -const Ice::Long TICKS_PER_MSECOND = 10000LL; -const Ice::Long MSECS_TO_EPOCH = 11644473600000LL; - IceUtil::Time filetimeToTime(FILETIME ftime) { @@ -419,6 +568,32 @@ certificateAltNames(CERT_INFO* certInfo, LPCSTR altNameOID) } return altNames; } +#else + +vector<pair<int, string> > +certificateAltNames(Windows::Security::Cryptography::Certificates::SubjectAlternativeNameInfo^ subAltNames) +{ + vector<pair<int, string> > altNames; + for (auto iter = subAltNames->EmailName->First(); iter->HasCurrent; iter->MoveNext()) + { + altNames.push_back(make_pair(AltNameEmail, IceUtil::wstringToString(iter->Current->Data()))); + } + for (auto iter = subAltNames->DnsName->First(); iter->HasCurrent; iter->MoveNext()) + { + altNames.push_back(make_pair(AltNameDNS, IceUtil::wstringToString(iter->Current->Data()))); + } + for (auto iter = subAltNames->Url->First(); iter->HasCurrent; iter->MoveNext()) + { + altNames.push_back(make_pair(AltNameURL, IceUtil::wstringToString(iter->Current->Data()))); + } + for (auto iter = subAltNames->IPAddress->First(); iter->HasCurrent; iter->MoveNext()) + { + altNames.push_back(make_pair(AltNAmeIP, IceUtil::wstringToString(iter->Current->Data()))); + } + return altNames; +} +#endif + #endif CertificateReadException::CertificateReadException(const char* file, int line, const string& r) : @@ -700,21 +875,25 @@ ParseException::ice_throw() const } #ifdef ICE_USE_OPENSSL -DistinguishedName::DistinguishedName(X509NAME* name) : - _rdns(RFC2253::parseStrict(convertX509NameToString(name))) +DistinguishedName::DistinguishedName(X509NAME* name) : _rdns(RFC2253::parseStrict(convertX509NameToString(name))) { unescape(); } #endif -DistinguishedName::DistinguishedName(const string& dn) : - _rdns(RFC2253::parseStrict(dn)) +#if defined(ICE_USE_SECURE_TRANSPORT_IOS) +DistinguishedName::DistinguishedName(CFDataRef data) : _rdns(ASN1Parser(data).parse()) { unescape(); } +#endif -DistinguishedName::DistinguishedName(const list<pair<string, string> >& rdns) : - _rdns(rdns) +DistinguishedName::DistinguishedName(const string& dn) : _rdns(RFC2253::parseStrict(dn)) +{ + unescape(); +} + +DistinguishedName::DistinguishedName(const list<pair<string, string> >& rdns) : _rdns(rdns) { unescape(); } @@ -810,7 +989,7 @@ PublicKey::~PublicKey() { # if defined(ICE_USE_SECURE_TRANSPORT) CFRelease(_key); -# else +# elif defined(ICE_USE_OPENSSL) EVP_PKEY_free(_key); # endif } @@ -827,9 +1006,6 @@ PublicKey::key() const // The caller is responsible for incrementing the reference count. // Certificate::Certificate(X509CertificateRef cert) : _cert(cert) -#ifdef ICE_USE_SCHANNEL - , _certInfo(0) -#endif { if(!_cert) { @@ -837,6 +1013,7 @@ Certificate::Certificate(X509CertificateRef cert) : _cert(cert) } #ifdef ICE_USE_SCHANNEL + _certInfo = 0; try { // @@ -856,13 +1033,28 @@ Certificate::Certificate(X509CertificateRef cert) : _cert(cert) throw; } #endif + +#if defined(ICE_USE_SECURE_TRANSPORT_IOS) + _subject = NULL; + _issuer = NULL; +#endif } Certificate::~Certificate() { if(_cert) { -#if defined(ICE_USE_SECURE_TRANSPORT) +#if defined(ICE_USE_SECURE_TRANSPORT_IOS) + if(_subject) + { + CFRelease(_subject); + } + if(_issuer) + { + CFRelease(_issuer); + } + CFRelease(_cert); +#elif defined(ICE_USE_SECURE_TRANSPORT_MACOS) CFRelease(_cert); #elif defined(ICE_USE_SCHANNEL) LocalFree(_cert); @@ -870,7 +1062,7 @@ Certificate::~Certificate() { LocalFree(_certInfo); } -#else +#elif defined(ICE_USE_OPENSSL) X509_free(_cert); #endif } @@ -880,12 +1072,20 @@ CertificatePtr Certificate::load(const string& file) { #if defined(ICE_USE_SECURE_TRANSPORT) - return ICE_MAKE_SHARED(Certificate, loadCertificate(file)); + string resolved; + if(checkPath(file, "", false, resolved)) + { + return ICE_MAKE_SHARED(Certificate, loadCertificate(resolved)); + } + else + { + throw CertificateReadException(__FILE__, __LINE__, "error opening file " + file); + } #elif defined(ICE_USE_SCHANNEL) CERT_SIGNED_CONTENT_INFO* cert; loadCertificate(&cert, file); return ICE_MAKE_SHARED(Certificate, cert); -#else +#elif defined(ICE_USE_OPENSSL) BIO *cert = BIO_new(BIO_s_file()); if(BIO_read_filename(cert, file.c_str()) <= 0) { @@ -901,16 +1101,45 @@ Certificate::load(const string& file) } BIO_free(cert); return ICE_MAKE_SHARED(Certificate, x); +#elif defined(ICE_OS_WINRT) + // TODO + return ICE_NULLPTR; +#else +# error "Unknown platform" #endif } CertificatePtr Certificate::decode(const string& encoding) { -#if defined(ICE_USE_SECURE_TRANSPORT) +#if defined(ICE_USE_SECURE_TRANSPORT_IOS) + string::size_type size, startpos, endpos = 0; + startpos = encoding.find("-----BEGIN CERTIFICATE-----", endpos); + if(startpos != string::npos) + { + startpos += sizeof("-----BEGIN CERTIFICATE-----"); + endpos = encoding.find("-----END CERTIFICATE-----", startpos); + size = endpos - startpos; + } + else + { + startpos = 0; + endpos = string::npos; + size = encoding.size(); + } + + vector<unsigned char> data(IceInternal::Base64::decode(string(&encoding[startpos], size))); + UniqueRef<CFDataRef> certdata(CFDataCreate(kCFAllocatorDefault, &data[0], data.size())); + SecCertificateRef cert = SecCertificateCreateWithData(0, certdata.get()); + if(!cert) + { + assert(false); + throw CertificateEncodingException(__FILE__, __LINE__, "certificate is not a valid PEM-encoded certificate"); + } + return ICE_MAKE_SHARED(Certificate, cert); +#elif defined(ICE_USE_SECURE_TRANSPORT_MACOS) CFDataRef data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, reinterpret_cast<const UInt8*>(encoding.c_str()), encoding.size(), kCFAllocatorNull); - SecExternalFormat format = kSecFormatUnknown; SecExternalItemType type = kSecItemTypeCertificate; @@ -929,14 +1158,13 @@ Certificate::decode(const string& encoding) SecKeychainItemRef item = (SecKeychainItemRef)CFArrayGetValueAtIndex(items, 0); CFRetain(item); CFRelease(items); - assert(SecCertificateGetTypeID() == CFGetTypeID(item)); return ICE_MAKE_SHARED(Certificate, (SecCertificateRef)item); #elif defined(ICE_USE_SCHANNEL) CERT_SIGNED_CONTENT_INFO* cert; loadCertificate(&cert, encoding.c_str(), static_cast<DWORD>(encoding.size())); return ICE_MAKE_SHARED(Certificate, cert); -#else +#elif defined(ICE_USE_OPENSSL) BIO *cert = BIO_new_mem_buf(static_cast<void*>(const_cast<char*>(&encoding[0])), static_cast<int>(encoding.size())); X509CertificateRef x = PEM_read_bio_X509_AUX(cert, NULL, NULL, NULL); if(x == NULL) @@ -946,6 +1174,11 @@ Certificate::decode(const string& encoding) } BIO_free(cert); return ICE_MAKE_SHARED(Certificate, x); +#elif defined(ICE_OS_WINRT) + // TODO + return ICE_NULLPTR; +#else +# error "Unknown platform" #endif } @@ -956,27 +1189,27 @@ Certificate::operator==(const Certificate& other) const return CFEqual(_cert, other._cert); #elif defined(ICE_USE_SCHANNEL) return CertCompareCertificate(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, _certInfo, other._certInfo); -#else +#elif defined(ICE_USE_OPENSSL) return X509_cmp(_cert, other._cert) == 0; +#elif defined(ICE_OS_WINRT) + return _cert->Equals(other._cert); +#else +# error "Unknown platform" #endif } bool Certificate::operator!=(const Certificate& other) const { -#if defined(ICE_USE_SECURE_TRANSPORT) - return !CFEqual(_cert, other._cert); -#elif defined(ICE_USE_SCHANNEL) - return !CertCompareCertificate(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, _certInfo, other._certInfo); -#else - return X509_cmp(_cert, other._cert) != 0; -#endif + return !operator==(other); } PublicKeyPtr Certificate::getPublicKey() const { -#if defined(ICE_USE_SECURE_TRANSPORT) +#if defined(ICE_USE_SECURE_TRANSPORT_IOS) + return ICE_NULLPTR; // Not supported +#elif defined(ICE_USE_SECURE_TRANSPORT_MACOS) SecKeyRef key; OSStatus err = SecCertificateCopyPublicKey(_cert, &key); if(err) @@ -986,8 +1219,12 @@ Certificate::getPublicKey() const return ICE_MAKE_SHARED(PublicKey, shared_from_this(), key); #elif defined(ICE_USE_SCHANNEL) return ICE_MAKE_SHARED(PublicKey, shared_from_this(), &_certInfo->SubjectPublicKeyInfo); -#else +#elif defined(ICE_USE_OPENSSL) return ICE_MAKE_SHARED(PublicKey, shared_from_this(), X509_get_pubkey(_cert)); +#elif defined(ICE_OS_WINRT) + return ICE_NULLPTR; // Not supported +#else +# error "Unknown platform" #endif } @@ -996,17 +1233,20 @@ Certificate::verify(const CertificatePtr& cert) const { #if defined(ICE_USE_SECURE_TRANSPORT) // - // We first check if the given certificate subject match - // our certificate issuer. Otherwhise when use SecTrustEvaluate - // and check a certificate against itself will always return - // that is valid. + // We first check if the given certificate subject match our certificate + // issuer. Otherwhise when checking a certificate against itself + // SecTrustEvaluate always returns it is valid. // bool valid = false; - CFErrorRef error = 0; +#if defined(ICE_USE_SECURE_TRANSPORT_IOS) + initializeAttributes(); + cert->initializeAttributes(); + valid = CFEqual(_issuer, cert->_subject); +#else CFDataRef issuer = 0; CFDataRef subject = 0; - + CFErrorRef error = 0; try { issuer = SecCertificateCopyNormalizedIssuerContent(_cert, &error); @@ -1042,7 +1282,7 @@ Certificate::verify(const CertificatePtr& cert) const CFRelease(issuer); CFRelease(subject); - +#endif if(valid) { SecPolicyRef policy = 0; @@ -1107,8 +1347,12 @@ Certificate::verify(const CertificatePtr& cert) const bool result = CryptVerifyCertificateSignature(0, X509_ASN_ENCODING, buffer, length, cert->getPublicKey()->key()); LocalFree(buffer); return result; -#else +#elif defined(ICE_USE_OPENSSL) return X509_verify(_cert, cert->getPublicKey()->key()) > 0; +#elif defined(ICE_OS_WINRT) + return false; +#else +# error "Unknown platform" #endif } @@ -1123,7 +1367,15 @@ Certificate::verify(const PublicKeyPtr& key) const string Certificate::encode() const { -#if defined(ICE_USE_SECURE_TRANSPORT) +#if defined(ICE_USE_SECURE_TRANSPORT_IOS) + UniqueRef<CFDataRef> c(SecCertificateCopyData(_cert)); + vector<unsigned char> data(CFDataGetBytePtr(c.get()), CFDataGetBytePtr(c.get()) + CFDataGetLength(c.get())); + ostringstream os; + os << "-----BEGIN CERTIFICATE-----\n"; + os << IceInternal::Base64::encode(data); + os << "-----END CERTIFICATE-----\n"; + return os.str(); +#elif defined(ICE_USE_SECURE_TRANSPORT_MACOS) CFDataRef exported; OSStatus err = SecItemExport(_cert, kSecFormatPEMSequence, kSecItemPemArmour, 0, &exported); if(err != noErr) @@ -1170,7 +1422,7 @@ Certificate::encode() const throw; } return s; -#else +#elif defined(ICE_USE_OPENSSL) BIO* out = BIO_new(BIO_s_mem()); int i = PEM_write_bio_X509_AUX(out, _cert); if(i <= 0) @@ -1183,9 +1435,25 @@ Certificate::encode() const string result = string(p->data, p->length); BIO_free(out); return result; +#elif defined(ICE_OS_WINRT) + auto reader = Windows::Storage::Streams::DataReader::FromBuffer(_cert->GetCertificateBlob()); + std::vector<unsigned char> data(reader->UnconsumedBufferLength); + if (!data.empty()) + { + reader->ReadBytes(Platform::ArrayReference<unsigned char>(&data[0], data.size())); + } + ostringstream os; + os << "-----BEGIN CERTIFICATE-----\n"; + os << IceInternal::Base64::encode(data); + os << "-----END CERTIFICATE-----\n"; + return os.str(); +#else +# error "Unknown platform" #endif } +#if !defined(ICE_USE_SECURE_TRANSPORT_IOS) + bool Certificate::checkValidity() const { @@ -1206,8 +1474,13 @@ Certificate::getNotAfter() const return getX509Date(_cert, kSecOIDX509V1ValidityNotAfter); #elif defined(ICE_USE_SCHANNEL) return filetimeToTime(_certInfo->NotAfter); -#else +#elif defined(ICE_USE_OPENSSL) return ASMUtcTimeToIceUtilTime(X509_get_notAfter(_cert)); +#elif defined(ICE_OS_WINRT) + // Convert 100ns time from January 1, 1601 to ms from January 1, 1970 + return IceUtil::Time::milliSeconds(_cert->ValidTo.UniversalTime / TICKS_PER_MSECOND - MSECS_TO_EPOCH); +#else +# error "Unknown platform" #endif } @@ -1218,15 +1491,25 @@ Certificate::getNotBefore() const return getX509Date(_cert, kSecOIDX509V1ValidityNotBefore); #elif defined(ICE_USE_SCHANNEL) return filetimeToTime(_certInfo->NotBefore); -#else +#elif defined(ICE_USE_OPENSSL) return ASMUtcTimeToIceUtilTime(X509_get_notBefore(_cert)); +#elif defined(ICE_OS_WINRT) + // Convert 100ns time from January 1, 1601 to ms from January 1, 1970 + return IceUtil::Time::milliSeconds(_cert->ValidFrom.UniversalTime / TICKS_PER_MSECOND - MSECS_TO_EPOCH); +#else +# error "Unknown platform" #endif } +#endif + string Certificate::getSerialNumber() const { -#if defined(ICE_USE_SECURE_TRANSPORT) +#if defined(ICE_USE_SECURE_TRANSPORT_IOS) + initializeAttributes(); + return _serial; +#elif defined(ICE_USE_SECURE_TRANSPORT_MACOS) return getX509String(_cert, kSecOIDX509V1SerialNumber); #elif defined(ICE_USE_SCHANNEL) ostringstream os; @@ -1235,14 +1518,14 @@ Certificate::getSerialNumber() const unsigned char c = _certInfo->SerialNumber.pbData[i]; os.fill('0'); os.width(2); - os << hex << (int)c; + os << hex << static_cast<int>(c); if(i) { os << ' '; } } return IceUtilInternal::toUpper(os.str()); -#else +#elif defined(ICE_USE_OPENSSL) BIGNUM* bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(_cert), 0); char* dec = BN_bn2dec(bn); string result = dec; @@ -1250,31 +1533,40 @@ Certificate::getSerialNumber() const BN_free(bn); return result; +#elif defined(ICE_OS_WINRT) + ostringstream os; + os.fill(0); + os.width(2); + for (unsigned int i = 0; i < _cert->SerialNumber->Length; i++) + { + os << hex << static_cast<int>(_cert->SerialNumber[i]); + } + return IceUtilInternal::toUpper(os.str()); +#else +# error "Unknown platform" #endif } -//string -//Certificate::getSigAlgName() const -//{ -//} - -//string -//Certificate::getSigAlgOID() const -//{ -//} - DistinguishedName Certificate::getIssuerDN() const { -#if defined(ICE_USE_SECURE_TRANSPORT) +#if defined(ICE_USE_SECURE_TRANSPORT_IOS) + initializeAttributes(); + return _issuer ? DistinguishedName(_issuer) : DistinguishedName(""); +#elif defined(ICE_USE_SECURE_TRANSPORT_MACOS) return getX509Name(_cert, kSecOIDX509V1IssuerName); #elif defined(ICE_USE_SCHANNEL) return DistinguishedName(certNameToString(&_certInfo->Issuer)); -#else +#elif defined(ICE_USE_OPENSSL) return DistinguishedName(RFC2253::parseStrict(convertX509NameToString(X509_get_issuer_name(_cert)))); +#elif defined(ICE_OS_WINRT) + return DistinguishedName(IceUtil::wstringToString(_cert->Issuer->Data())); +#else +# error "Unknown platform" #endif } +#if !defined(ICE_USE_SECURE_TRANSPORT_IOS) vector<pair<int, string> > Certificate::getIssuerAlternativeNames() { @@ -1282,23 +1574,45 @@ Certificate::getIssuerAlternativeNames() return getX509AltName(_cert, kSecOIDIssuerAltName); #elif defined(ICE_USE_SCHANNEL) return certificateAltNames(_certInfo, szOID_ISSUER_ALT_NAME2); -#else +#elif defined(ICE_USE_OPENSSL) return convertGeneralNames(reinterpret_cast<GENERAL_NAMES*>(X509_get_ext_d2i(_cert, NID_issuer_alt_name, 0, 0))); +#elif defined(ICE_OS_WINRT) + return vector<pair<int, string> >(); // Not supported +#else +# error "Unknown platform" #endif } +#endif DistinguishedName Certificate::getSubjectDN() const { -#if defined(ICE_USE_SECURE_TRANSPORT) +#if defined(ICE_USE_SECURE_TRANSPORT_IOS) + initializeAttributes(); + if(_subject) + { + return DistinguishedName(_subject); + } + else + { + string s = "CN="; + s += fromCFString(UniqueRef<CFStringRef>(SecCertificateCopySubjectSummary(_cert)).get()); + return DistinguishedName(s); + } +#elif defined(ICE_USE_SECURE_TRANSPORT_MACOS) return getX509Name(_cert, kSecOIDX509V1SubjectName); #elif defined(ICE_USE_SCHANNEL) return DistinguishedName(certNameToString(&_certInfo->Subject)); -#else +#elif defined(ICE_USE_OPENSSL) return DistinguishedName(RFC2253::parseStrict(convertX509NameToString(X509_get_subject_name(_cert)))); +#elif defined(ICE_OS_WINRT) + return DistinguishedName(IceUtil::wstringToString(_cert->Subject->Data())); +#else +# error "Unknown platform" #endif } +#if !defined(ICE_USE_SECURE_TRANSPORT_IOS) vector<pair<int, string> > Certificate::getSubjectAlternativeNames() { @@ -1306,20 +1620,32 @@ Certificate::getSubjectAlternativeNames() return getX509AltName(_cert, kSecOIDSubjectAltName); #elif defined(ICE_USE_SCHANNEL) return certificateAltNames(_certInfo, szOID_SUBJECT_ALT_NAME2); -#else +#elif defined(ICE_USE_OPENSSL) return convertGeneralNames(reinterpret_cast<GENERAL_NAMES*>(X509_get_ext_d2i(_cert, NID_subject_alt_name, 0, 0))); +#elif defined(ICE_OS_WINRT) + return certificateAltNames(_cert->SubjectAlternativeName); +#else +# error "Unknown platform" #endif } +#endif int Certificate::getVersion() const { -#if defined(ICE_USE_SECURE_TRANSPORT) +#if defined(ICE_USE_SECURE_TRANSPORT_IOS) + initializeAttributes(); + return _version; +#elif defined(ICE_USE_SECURE_TRANSPORT_MACOS) return atoi(getX509String(_cert, kSecOIDX509V1Version).c_str()) - 1; #elif defined(ICE_USE_SCHANNEL) return _certInfo->dwVersion; -#else +#elif defined(ICE_USE_OPENSSL) return static_cast<int>(X509_get_version(_cert)); +#elif defined(ICE_OS_WINRT) + return -1; // Not supported +#else +# error "Unknown platform" #endif } @@ -1330,8 +1656,10 @@ Certificate::toString() const os << "serial: " << getSerialNumber() << "\n"; os << "issuer: " << string(getIssuerDN()) << "\n"; os << "subject: " << string(getSubjectDN()) << "\n"; +#if !defined(ICE_USE_SECURE_TRANSPORT_IOS) os << "notBefore: " << getNotBefore().toDateTime() << "\n"; os << "notAfter: " << getNotAfter().toDateTime(); +#endif return os.str(); } @@ -1340,3 +1668,101 @@ Certificate::getCert() const { return _cert; } + +#if defined(ICE_USE_SECURE_TRANSPORT_IOS) + +namespace +{ + +IceUtil::Mutex* globalMutex = 0; + +class Init +{ +public: + + Init() + { + globalMutex = new IceUtil::Mutex; + } + + ~Init() + { + delete globalMutex; + globalMutex = 0; + } +}; + +Init init; + +} + +void +Certificate::initializeAttributes() const +{ + if(_subject) + { + return; + } + + // + // We need to temporarily add the certificate to the keychain in order to + // retrieve its attributes. Unfortunately kSecMatchItemList doesn't work + // on iOS. We make sure only one thread adds/removes a cert at a time here. + // + IceUtilInternal::MutexPtrLock<IceUtil::Mutex> lock(globalMutex); + + CFMutableDictionaryRef query; + + query = CFDictionaryCreateMutable(0, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + CFDictionarySetValue(query, kSecValueRef, _cert); + CFDictionarySetValue(query, kSecReturnAttributes, kCFBooleanTrue); + CFDictionaryRef attributes; + OSStatus err; + if((err = SecItemAdd(query, (CFTypeRef*)&attributes)) == errSecDuplicateItem) + { + CFDictionarySetValue(query, kSecClass, kSecClassCertificate); + err = SecItemCopyMatching(query, (CFTypeRef*)&attributes); + } + else + { + CFRelease(query); + query = CFDictionaryCreateMutable(0, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + CFDictionarySetValue(query, kSecClass, kSecClassCertificate); + CFDictionarySetValue(query, kSecValueRef, _cert); + err = SecItemDelete(query); + } + CFRelease(query); + if(err != noErr) + { + _subject = 0; + _issuer = 0; + return; + } + + _subject = (CFDataRef)CFDictionaryGetValue(attributes, kSecAttrSubject); + _issuer = (CFDataRef)CFDictionaryGetValue(attributes, kSecAttrIssuer); + CFDataRef serial = (CFDataRef)CFDictionaryGetValue(attributes, kSecAttrSerialNumber); + ostringstream os; + for(int i = 0; i < CFDataGetLength(serial); ++i) + { + int c = static_cast<int>(CFDataGetBytePtr(serial)[i]); + if(i) + { + os << ' '; + } + os.fill('0'); + os.width(2); + os << hex << c; + } + _serial = os.str(); + CFNumberRef version = (CFNumberRef)CFDictionaryGetValue(attributes, kSecAttrCertificateType); + if(!CFNumberGetValue(version, kCFNumberIntType, &_version)) + { + _version = -1; + } + CFRetain(_subject); + CFRetain(_issuer); + + CFRelease(attributes); +} +#endif
\ No newline at end of file diff --git a/cpp/src/IceSSL/ConnectorI.cpp b/cpp/src/IceSSL/ConnectorI.cpp index 51a79e1929f..532847ec0ed 100644 --- a/cpp/src/IceSSL/ConnectorI.cpp +++ b/cpp/src/IceSSL/ConnectorI.cpp @@ -13,6 +13,7 @@ #include <IceSSL/OpenSSLTransceiverI.h> #include <IceSSL/SecureTransportTransceiverI.h> #include <IceSSL/SChannelTransceiverI.h> +#include <IceSSL/WinRTTransceiverI.h> #include <IceSSL/EndpointI.h> #include <IceSSL/Util.h> @@ -39,20 +40,19 @@ IceSSL::ConnectorI::connect() throw ex; } - IceInternal::StreamSocketPtr stream = new IceInternal::StreamSocket(_instance, _proxy, _addr, _sourceAddr); - return new TransceiverI(_instance, stream, _host, false); + return new TransceiverI(_instance, _delegate->connect(), _host, false); } Short IceSSL::ConnectorI::type() const { - return _instance->type(); + return _delegate->type(); } string IceSSL::ConnectorI::toString() const { - return IceInternal::addrToString(!_proxy ? _addr : _proxy->getAddress()); + return _delegate->toString(); } bool @@ -64,22 +64,12 @@ IceSSL::ConnectorI::operator==(const IceInternal::Connector& r) const return false; } - if(IceInternal::compareAddress(_addr, p->_addr) != 0) + if(this == p) { - return false; - } - - if(_timeout != p->_timeout) - { - return false; - } - - if(IceInternal::compareAddress(_sourceAddr, p->_sourceAddr) != 0) - { - return false; + return true; } - if(_connectionId != p->_connectionId) + if(_delegate != p->_delegate) { return false; } @@ -102,47 +92,25 @@ IceSSL::ConnectorI::operator<(const IceInternal::Connector& r) const return type() < r.type(); } - if(_timeout < p->_timeout) - { - return true; - } - else if(p->_timeout < _timeout) - { - return false; - } - - int rc = compareAddress(_sourceAddr, p->_sourceAddr); - if(rc < 0) - { - return true; - } - else if(rc > 0) + if(this == p) { return false; } - if(_connectionId < p->_connectionId) + if(_delegate < p->_delegate) { return true; } - else if(p->_connectionId < _connectionId) + else if(p->_delegate < _delegate) { return false; } - return IceInternal::compareAddress(_addr, p->_addr) == -1; + return false; } -IceSSL::ConnectorI::ConnectorI(const InstancePtr& instance, const string& host, const IceInternal::Address& addr, - const IceInternal::NetworkProxyPtr& proxy, const IceInternal::Address& sourceAddr, - Ice::Int timeout, const string& connectionId) : - _instance(instance), - _host(host), - _addr(addr), - _proxy(proxy), - _sourceAddr(sourceAddr), - _timeout(timeout), - _connectionId(connectionId) +IceSSL::ConnectorI::ConnectorI(const InstancePtr& instance, const IceInternal::ConnectorPtr& del, const string& h) : + _instance(instance), _delegate(del), _host(h) { } diff --git a/cpp/src/IceSSL/ConnectorI.h b/cpp/src/IceSSL/ConnectorI.h index 48a80fdebcc..e1434d97d1b 100644 --- a/cpp/src/IceSSL/ConnectorI.h +++ b/cpp/src/IceSSL/ConnectorI.h @@ -36,19 +36,13 @@ public: private: - ConnectorI(const InstancePtr&, const std::string&, const IceInternal::Address&, - const IceInternal::NetworkProxyPtr&, const IceInternal::Address&, - Ice::Int, const std::string&); + ConnectorI(const InstancePtr&, const IceInternal::ConnectorPtr&, const std::string&); virtual ~ConnectorI(); friend class EndpointI; const InstancePtr _instance; + const IceInternal::ConnectorPtr _delegate; const std::string _host; - const IceInternal::Address _addr; - const IceInternal::NetworkProxyPtr _proxy; - const IceInternal::Address _sourceAddr; - const Ice::Int _timeout; - const std::string _connectionId; }; } diff --git a/cpp/src/IceSSL/EndpointI.cpp b/cpp/src/IceSSL/EndpointI.cpp index 0038cf9717f..1615b12d05d 100644 --- a/cpp/src/IceSSL/EndpointI.cpp +++ b/cpp/src/IceSSL/EndpointI.cpp @@ -17,101 +17,135 @@ #include <Ice/DefaultsAndOverrides.h> #include <Ice/Object.h> #include <Ice/HashUtil.h> +#include <Ice/Comparable.h> using namespace std; using namespace Ice; using namespace IceSSL; -#ifndef ICE_CPP11_MAPPING -IceUtil::Shared* IceSSL::upCast(EndpointI* p) { return p; } -#endif +namespace +{ -IceSSL::EndpointI::EndpointI(const InstancePtr& instance, const string& ho, Int po, - const IceInternal::Address& sourceAddr, Int ti, const string& conId, bool co) : - IceInternal::IPEndpointI(instance, ho, po, sourceAddr, conId), - _instance(instance), - _timeout(ti), - _compress(co) +Ice::IPEndpointInfoPtr +getIPEndpointInfo(const Ice::EndpointInfoPtr& info) { + for(Ice::EndpointInfoPtr p = info; p; p = p->underlying) + { + Ice::IPEndpointInfoPtr ipInfo = ICE_DYNAMIC_CAST(Ice::IPEndpointInfo, p); + if(ipInfo) + { + return ipInfo; + } + } + return ICE_NULLPTR; } -IceSSL::EndpointI::EndpointI(const InstancePtr& instance) : - IceInternal::IPEndpointI(instance), - _instance(instance), - _timeout(instance->defaultTimeout()), - _compress(false) +} + +#ifndef ICE_CPP11_MAPPING +IceUtil::Shared* IceSSL::upCast(EndpointI* p) { return p; } +#endif + +IceSSL::EndpointI::EndpointI(const InstancePtr& instance, const IceInternal::EndpointIPtr& del) : + _instance(instance), _delegate(del) { } -IceSSL::EndpointI::EndpointI(const InstancePtr& instance, Ice::InputStream* s) : - IPEndpointI(instance, s), - _instance(instance), - _timeout(-1), - _compress(false) +void +IceSSL::EndpointI::streamWriteImpl(Ice::OutputStream* stream) const { - s->read(const_cast<Int&>(_timeout)); - s->read(const_cast<bool&>(_compress)); + _delegate->streamWriteImpl(stream); } Ice::EndpointInfoPtr IceSSL::EndpointI::getInfo() const { EndpointInfoPtr info = ICE_MAKE_SHARED(IceInternal::InfoI<EndpointInfo>, shared_from_this()); - fillEndpointInfo(info.get()); + info->underlying = _delegate->getInfo(); + info->compress = info->underlying->compress; + info->timeout = info->underlying->timeout; return info; } -Ice::EndpointInfoPtr -IceSSL::EndpointI::getWSInfo(const string& resource) const +Ice::Short +IceSSL::EndpointI::type() const { - WSSEndpointInfoPtr info = ICE_MAKE_SHARED(IceInternal::InfoI<WSSEndpointInfo>, shared_from_this()); - fillEndpointInfo(info.get()); - info->resource = resource; - return info; + return _delegate->type(); +} + +const std::string& +IceSSL::EndpointI::protocol() const +{ + return _delegate->protocol(); } Int IceSSL::EndpointI::timeout() const { - return _timeout; + return _delegate->timeout(); } IceInternal::EndpointIPtr IceSSL::EndpointI::timeout(Int timeout) const { - if(timeout == _timeout) + if(timeout == _delegate->timeout()) { return shared_from_this(); } else { - return ICE_MAKE_SHARED(EndpointI, _instance, _host, _port, _sourceAddr, timeout, _connectionId, _compress); + return ICE_MAKE_SHARED(EndpointI, _instance, _delegate->timeout(timeout)); + } +} + +const string& +IceSSL::EndpointI::connectionId() const +{ + return _delegate->connectionId(); +} + +IceInternal::EndpointIPtr +IceSSL::EndpointI::connectionId(const string& connectionId) const +{ + if(connectionId == _delegate->connectionId()) + { + return shared_from_this(); + } + else + { + return ICE_MAKE_SHARED(EndpointI, _instance, _delegate->connectionId(connectionId)); } } bool IceSSL::EndpointI::compress() const { - return _compress; + return _delegate->compress(); } IceInternal::EndpointIPtr IceSSL::EndpointI::compress(bool compress) const { - if(compress == _compress) + if(compress == _delegate->compress()) { return shared_from_this(); } else { - return ICE_MAKE_SHARED(EndpointI, _instance, _host, _port, _sourceAddr, _timeout, _connectionId, compress); + return ICE_MAKE_SHARED(EndpointI, _instance, _delegate->compress(compress)); } } bool IceSSL::EndpointI::datagram() const { - return false; + return _delegate->datagram(); +} + +bool +IceSSL::EndpointI::secure() const +{ + return _delegate->secure(); } IceInternal::TransceiverPtr @@ -120,46 +154,90 @@ IceSSL::EndpointI::transceiver() const return 0; } +void +IceSSL::EndpointI::connectors_async(Ice::EndpointSelectionType selType, + const IceInternal::EndpointI_connectorsPtr& callback) const +{ + class CallbackI : public IceInternal::EndpointI_connectors + { + public: + + CallbackI(const IceInternal::EndpointI_connectorsPtr& callback, const InstancePtr& instance, + const string& host) : + _callback(callback), _instance(instance), _host(host) + { + } + + virtual void connectors(const vector<IceInternal::ConnectorPtr>& c) + { + vector<IceInternal::ConnectorPtr> connectors = c; + for(vector<IceInternal::ConnectorPtr>::iterator p = connectors.begin(); p != connectors.end(); ++p) + { + *p = new ConnectorI(_instance, *p, _host); + } + _callback->connectors(connectors); + } + + virtual void exception(const Ice::LocalException& ex) + { + _callback->exception(ex); + } + + private: + + const IceInternal::EndpointI_connectorsPtr _callback; + const InstancePtr _instance; + const string _host; + }; + + IPEndpointInfoPtr info = getIPEndpointInfo(_delegate->getInfo()); + _delegate->connectors_async(selType, ICE_MAKE_SHARED(CallbackI, callback, _instance, info ? info->host : string())); +} + IceInternal::AcceptorPtr IceSSL::EndpointI::acceptor(const string& adapterName) const { - return new AcceptorI(ICE_DYNAMIC_CAST(IceSSL::EndpointI, shared_from_this()), _instance, adapterName, _host, _port); + return new AcceptorI(shared_from_this(), _instance, _delegate->acceptor(adapterName), adapterName); } EndpointIPtr -IceSSL::EndpointI::endpoint(const AcceptorIPtr& acceptor) const +IceSSL::EndpointI::endpoint(const IceInternal::EndpointIPtr& delEndp) const { - return ICE_MAKE_SHARED(EndpointI, _instance, _host, acceptor->effectivePort(), _sourceAddr, _timeout, _connectionId, _compress); + return ICE_MAKE_SHARED(EndpointI, _instance, delEndp); } -string -IceSSL::EndpointI::options() const +vector<IceInternal::EndpointIPtr> +IceSSL::EndpointI::expand() const { - // - // WARNING: Certain features, such as proxy validation in Glacier2, - // depend on the format of proxy strings. Changes to toString() and - // methods called to generate parts of the reference string could break - // these features. Please review for all features that depend on the - // format of proxyToString() before changing this and related code. - // - ostringstream s; - s << IPEndpointI::options(); - - if(_timeout == -1) + vector<IceInternal::EndpointIPtr> endps = _delegate->expand(); + for(vector<IceInternal::EndpointIPtr>::iterator p = endps.begin(); p != endps.end(); ++p) { - s << " -t infinite"; - } - else - { - s << " -t " << _timeout; + *p = p->get() == _delegate.get() ? shared_from_this() : ICE_MAKE_SHARED(EndpointI, _instance, *p); } + return endps; +} - if(_compress) +bool +IceSSL::EndpointI::equivalent(const IceInternal::EndpointIPtr& endpoint) const +{ + const EndpointI* endpointI = dynamic_cast<const EndpointI*>(endpoint.get()); + if(!endpointI) { - s << " -z"; + return false; } + return _delegate->equivalent(endpointI->_delegate); +} + +Ice::Int +IceSSL::EndpointI::hash() const +{ + return _delegate->hash(); +} - return s.str(); +string +IceSSL::EndpointI::options() const +{ + return _delegate->options(); } bool @@ -169,11 +247,6 @@ IceSSL::EndpointI::operator==(const Ice::Endpoint& r) const IceSSL::EndpointI::operator==(const Ice::LocalObject& r) const #endif { - if(!IPEndpointI::operator==(r)) - { - return false; - } - const EndpointI* p = dynamic_cast<const EndpointI*>(&r); if(!p) { @@ -185,12 +258,7 @@ IceSSL::EndpointI::operator==(const Ice::LocalObject& r) const return true; } - if(_timeout != p->_timeout) - { - return false; - } - - if(_compress != p->_compress) + if(!Ice::targetEquals(_delegate, p->_delegate)) { return false; } @@ -221,119 +289,27 @@ IceSSL::EndpointI::operator<(const Ice::LocalObject& r) const return false; } - if(_timeout < p->_timeout) - { - return true; - } - else if(p->_timeout < _timeout) - { - return false; - } - - if(!_compress && p->_compress) + if(Ice::targetLess(_delegate, p->_delegate)) { return true; } - else if(p->_compress < _compress) + else if (Ice::targetLess(p->_delegate, _delegate)) { return false; } - return IPEndpointI::operator<(r); -} - -void -IceSSL::EndpointI::streamWriteImpl(Ice::OutputStream* s) const -{ - IPEndpointI::streamWriteImpl(s); - s->write(_timeout); - s->write(_compress); -} - -void -IceSSL::EndpointI::hashInit(Ice::Int& h) const -{ - IPEndpointI::hashInit(h); - IceInternal::hashAdd(h, _timeout); - IceInternal::hashAdd(h, _compress); -} - -void -IceSSL::EndpointI::fillEndpointInfo(IPEndpointInfo* info) const -{ - IPEndpointI::fillEndpointInfo(info); - info->timeout = _timeout; - info->compress = _compress; + return false; } bool IceSSL::EndpointI::checkOption(const string& option, const string& argument, const string& endpoint) { - if(IPEndpointI::checkOption(option, argument, endpoint)) - { - return true; - } - - switch(option[1]) - { - case 't': - { - if(argument.empty()) - { - EndpointParseException ex(__FILE__, __LINE__); - ex.str = "no argument provided for -t option in endpoint " + endpoint; - throw ex; - } - - if(argument == "infinite") - { - const_cast<Int&>(_timeout) = -1; - } - else - { - istringstream t(argument); - if(!(t >> const_cast<Int&>(_timeout)) || !t.eof() || _timeout < 1) - { - EndpointParseException ex(__FILE__, __LINE__); - ex.str = "invalid timeout value `" + argument + "' in endpoint " + endpoint; - throw ex; - } - } - return true; - } - - case 'z': - { - if(!argument.empty()) - { - EndpointParseException ex(__FILE__, __LINE__); - ex.str = "unexpected argument `" + argument + "' provided for -z option in " + endpoint; - throw ex; - } - const_cast<bool&>(_compress) = true; - return true; - } - - default: - { - return false; - } - } -} - -IceInternal::ConnectorPtr -IceSSL::EndpointI::createConnector(const IceInternal::Address& address, const IceInternal::NetworkProxyPtr& proxy) const -{ - return new ConnectorI(_instance, _host, address, proxy, _sourceAddr, _timeout, _connectionId); -} - -IceInternal::IPEndpointIPtr -IceSSL::EndpointI::createEndpoint(const string& host, int port, const string& connectionId) const -{ - return ICE_MAKE_SHARED(EndpointI, _instance, host, port, _sourceAddr, _timeout, connectionId, _compress); + return false; } -IceSSL::EndpointFactoryI::EndpointFactoryI(const InstancePtr& instance) : _instance(instance) +IceSSL::EndpointFactoryI::EndpointFactoryI(const InstancePtr& instance, + const IceInternal::EndpointFactoryPtr& delegate) : + _instance(instance), _delegate(delegate) { } @@ -356,25 +332,26 @@ IceSSL::EndpointFactoryI::protocol() const IceInternal::EndpointIPtr IceSSL::EndpointFactoryI::create(vector<string>& args, bool oaEndpoint) const { - IceInternal::IPEndpointIPtr endpt = ICE_MAKE_SHARED(EndpointI, _instance); - endpt->initWithOptions(args, oaEndpoint); - return endpt; + return ICE_MAKE_SHARED(EndpointI, _instance, _delegate->create(args, oaEndpoint)); } IceInternal::EndpointIPtr IceSSL::EndpointFactoryI::read(Ice::InputStream* s) const { - return ICE_MAKE_SHARED(EndpointI, _instance, s); + return ICE_MAKE_SHARED(EndpointI, _instance, _delegate->read(s)); } void IceSSL::EndpointFactoryI::destroy() { + _delegate->destroy(); _instance = 0; } IceInternal::EndpointFactoryPtr -IceSSL::EndpointFactoryI::clone(const IceInternal::ProtocolInstancePtr& instance) const +IceSSL::EndpointFactoryI::clone(const IceInternal::ProtocolInstancePtr& inst, + const IceInternal::EndpointFactoryPtr& delegate) const { - return new EndpointFactoryI(new Instance(_instance->engine(), instance->type(), instance->protocol())); + InstancePtr instance = new Instance(_instance->engine(), inst->type(), inst->protocol()); + return new EndpointFactoryI(instance, delegate ? delegate : _delegate->clone(instance, 0)); } diff --git a/cpp/src/IceSSL/EndpointI.h b/cpp/src/IceSSL/EndpointI.h index 0aec468f9c7..fd122d7b146 100644 --- a/cpp/src/IceSSL/EndpointI.h +++ b/cpp/src/IceSSL/EndpointI.h @@ -13,7 +13,6 @@ #include <Ice/EndpointI.h> #include <Ice/IPEndpointI.h> #include <Ice/EndpointFactory.h> -#include <Ice/WSEndpoint.h> #include <IceSSL/InstanceF.h> #include <IceSSL/EndpointInfo.h> #include <Ice/Network.h> @@ -21,28 +20,38 @@ namespace IceSSL { -class EndpointI : public IceInternal::IPEndpointI, public IceInternal::WSEndpointDelegate +class EndpointI : public IceInternal::EndpointI, public Ice::EnableSharedFromThis<EndpointI> { public: - EndpointI(const InstancePtr&, const std::string&, Ice::Int, const IceInternal::Address&, Ice::Int, - const std::string&, bool); - EndpointI(const InstancePtr&); - EndpointI(const InstancePtr&, Ice::InputStream*); + EndpointI(const InstancePtr&, const IceInternal::EndpointIPtr&); + + virtual void streamWriteImpl(Ice::OutputStream*) const; virtual Ice::EndpointInfoPtr getInfo() const; - virtual Ice::EndpointInfoPtr getWSInfo(const std::string&) const; + virtual Ice::Short type() const; + virtual const std::string& protocol() const; virtual Ice::Int timeout() const; virtual IceInternal::EndpointIPtr timeout(Ice::Int) const; + virtual const std::string& connectionId() const; + virtual IceInternal::EndpointIPtr connectionId(const ::std::string&) const; virtual bool compress() const; virtual IceInternal::EndpointIPtr compress(bool) const; virtual bool datagram() const; + virtual bool secure() const; virtual IceInternal::TransceiverPtr transceiver() const; + virtual void connectors_async(Ice::EndpointSelectionType, const IceInternal::EndpointI_connectorsPtr&) const; virtual IceInternal::AcceptorPtr acceptor(const std::string&) const; + + virtual std::vector<IceInternal::EndpointIPtr> expand() const; + virtual bool equivalent(const IceInternal::EndpointIPtr&) const; + virtual ::Ice::Int hash() const; virtual std::string options() const; + EndpointIPtr endpoint(const IceInternal::EndpointIPtr&) const; + #ifdef ICE_CPP11_MAPPING virtual bool operator==(const Ice::Endpoint&) const; virtual bool operator<(const Ice::Endpoint&) const; @@ -51,29 +60,17 @@ public: virtual bool operator<(const Ice::LocalObject&) const; #endif - virtual EndpointIPtr endpoint(const AcceptorIPtr&) const; - - using IceInternal::IPEndpointI::connectionId; - protected: - virtual void streamWriteImpl(Ice::OutputStream*) const; - virtual void hashInit(Ice::Int&) const; - virtual void fillEndpointInfo(Ice::IPEndpointInfo*) const; virtual bool checkOption(const std::string&, const std::string&, const std::string&); - virtual IceInternal::ConnectorPtr createConnector(const IceInternal::Address&, - const IceInternal::NetworkProxyPtr&) const; - virtual IceInternal::IPEndpointIPtr createEndpoint(const std::string&, int, const std::string&) const; - private: // // All members are const, because endpoints are immutable. // const InstancePtr _instance; - const Ice::Int _timeout; - const bool _compress; + const IceInternal::EndpointIPtr _delegate; }; class EndpointFactoryI : public IceInternal::EndpointFactory @@ -88,14 +85,16 @@ public: virtual IceInternal::EndpointIPtr read(Ice::InputStream*) const; virtual void destroy(); - virtual IceInternal::EndpointFactoryPtr clone(const IceInternal::ProtocolInstancePtr&) const; + virtual IceInternal::EndpointFactoryPtr clone(const IceInternal::ProtocolInstancePtr&, + const IceInternal::EndpointFactoryPtr&) const; private: - EndpointFactoryI(const InstancePtr&); + EndpointFactoryI(const InstancePtr&, const IceInternal::EndpointFactoryPtr&); friend class PluginI; InstancePtr _instance; + const IceInternal::EndpointFactoryPtr _delegate; }; } diff --git a/cpp/src/IceSSL/Instance.cpp b/cpp/src/IceSSL/Instance.cpp index b7f9ce3fdf4..e37ab14a967 100644 --- a/cpp/src/IceSSL/Instance.cpp +++ b/cpp/src/IceSSL/Instance.cpp @@ -7,13 +7,8 @@ // // ********************************************************************** -#include <IceUtil/Config.h> -#ifdef _WIN32 -# include <winsock2.h> -#endif #include <IceSSL/Instance.h> #include <IceSSL/SSLEngine.h> -#include <Ice/Properties.h> using namespace std; using namespace Ice; diff --git a/cpp/src/IceSSL/Instance.h b/cpp/src/IceSSL/Instance.h index 6a4514de52b..d9a25482eb0 100644 --- a/cpp/src/IceSSL/Instance.h +++ b/cpp/src/IceSSL/Instance.h @@ -10,8 +10,8 @@ #ifndef ICE_SSL_INSTANCE_H #define ICE_SSL_INSTANCE_H -#include <IceSSL/InstanceF.h> #include <Ice/ProtocolInstance.h> +#include <IceSSL/InstanceF.h> #include <IceSSL/SSLEngineF.h> namespace IceSSL @@ -24,12 +24,12 @@ public: Instance(const SSLEnginePtr&, Ice::Short, const std::string&); virtual ~Instance(); - SSLEnginePtr + SSLEnginePtr engine() const { return _engine; } - + bool initialized() const; private: diff --git a/cpp/src/IceSSL/Makefile.mk b/cpp/src/IceSSL/Makefile.mk index 3a6988f4879..0e2e3d00e94 100644 --- a/cpp/src/IceSSL/Makefile.mk +++ b/cpp/src/IceSSL/Makefile.mk @@ -11,10 +11,7 @@ $(project)_libraries := IceSSL IceSSL_targetdir := $(libdir) IceSSL_dependencies := Ice -IceSSL_cppflags := -DICESSL_API_EXPORTS -IceSSL_sliceflags := --include-dir IceSSL --dll-export ICESSL_API - -IceSSL[iphoneos]_excludes := $(wildcard $(addprefix $(currentdir)/,*.cpp)) -IceSSL[iphonesimulator]_excludes = $(IceSSL[iphoneos]_excludes) +IceSSL_cppflags := -DICE_SSL_API_EXPORTS +IceSSL_sliceflags := --include-dir IceSSL --dll-export ICE_SSL_API projects += $(project) diff --git a/cpp/src/IceSSL/OpenSSLTransceiverI.cpp b/cpp/src/IceSSL/OpenSSLTransceiverI.cpp index 2178c292ea0..de7fbb3ade6 100644 --- a/cpp/src/IceSSL/OpenSSLTransceiverI.cpp +++ b/cpp/src/IceSSL/OpenSSLTransceiverI.cpp @@ -79,16 +79,20 @@ IceSSL_opensslVerifyCallback(int ok, X509_STORE_CTX* ctx) IceInternal::NativeInfoPtr IceSSL::TransceiverI::getNativeInfo() { - return _stream; + return _delegate->getNativeInfo(); } IceInternal::SocketOperation IceSSL::TransceiverI::initialize(IceInternal::Buffer& readBuffer, IceInternal::Buffer& writeBuffer) { - IceInternal::SocketOperation status = _stream->connect(readBuffer, writeBuffer); - if(status != IceInternal::SocketOperationNone) + if(!_connected) { - return status; + IceInternal::SocketOperation status = _delegate->initialize(readBuffer, writeBuffer); + if(status != IceInternal::SocketOperationNone) + { + return status; + } + _connected = true; } if(!_ssl) @@ -96,7 +100,9 @@ IceSSL::TransceiverI::initialize(IceInternal::Buffer& readBuffer, IceInternal::B // // This static_cast is necessary due to 64bit windows. There SOCKET is a non-int type. // - BIO* bio = BIO_new_socket(static_cast<int>(_stream->fd()), 0); + SOCKET fd = _delegate->getNativeInfo()->fd(); + assert(fd != INVALID_SOCKET); // Underlying transport must be SOCKET based. + BIO* bio = BIO_new_socket(static_cast<int>(fd), 0); if(!bio) { SecurityException ex(__FILE__, __LINE__); @@ -231,15 +237,9 @@ IceSSL::TransceiverI::initialize(IceInternal::Buffer& readBuffer, IceInternal::B } case SSL_ERROR_SSL: { - IceInternal::Address remoteAddr; - string desc = "<not available>"; - if(IceInternal::fdToRemoteAddress(_stream->fd(), remoteAddr)) - { - desc = IceInternal::addrToString(remoteAddr); - } ostringstream ostr; ostr << "SSL error occurred for new " << (_incoming ? "incoming" : "outgoing") - << " connection:\nremote address = " << desc << "\n" << _engine->sslErrors(); + << " connection:\nremote address = " << _delegate->toString() << "\n" << _engine->sslErrors(); ProtocolException ex(__FILE__, __LINE__); ex.reason = ostr.str(); throw ex; @@ -278,12 +278,7 @@ IceSSL::TransceiverI::initialize(IceInternal::Buffer& readBuffer, IceInternal::B { _verified = true; } - -#ifdef ICE_CPP11_MAPPING - _engine->verifyPeer(_stream->fd(), _host, dynamic_pointer_cast<NativeConnectionInfo>(getInfo())); -#else - _engine->verifyPeer(_stream->fd(), _host, NativeConnectionInfoPtr::dynamicCast(getInfo())); -#endif + _engine->verifyPeer(_host, ICE_DYNAMIC_CAST(NativeConnectionInfo, getInfo()), toString()); if(_engine->securityTraceLevel() >= 1) { @@ -342,15 +337,15 @@ IceSSL::TransceiverI::close() _ssl = 0; } - _stream->close(); + _delegate->close(); } IceInternal::SocketOperation IceSSL::TransceiverI::write(IceInternal::Buffer& buf) { - if(!_stream->isConnected()) + if(!_connected) { - return _stream->write(buf); + return _delegate->write(buf); } if(buf.i == buf.b.end()) @@ -450,9 +445,9 @@ IceSSL::TransceiverI::write(IceInternal::Buffer& buf) IceInternal::SocketOperation IceSSL::TransceiverI::read(IceInternal::Buffer& buf) { - if(!_stream->isConnected()) + if(!_connected) { - return _stream->read(buf); + return _delegate->read(buf); } // @@ -466,7 +461,7 @@ IceSSL::TransceiverI::read(IceInternal::Buffer& buf) return IceInternal::SocketOperationNone; } - _stream->ready(IceInternal::SocketOperationRead, false); + _delegate->getNativeInfo()->ready(IceInternal::SocketOperationRead, false); // // It's impossible for packetSize to be more than an Int. @@ -560,7 +555,7 @@ IceSSL::TransceiverI::read(IceInternal::Buffer& buf) // // Check if there's still buffered data to read, set the read ready status. // - _stream->ready(IceInternal::SocketOperationRead, SSL_pending(_ssl) > 0); + _delegate->getNativeInfo()->ready(IceInternal::SocketOperationRead, SSL_pending(_ssl) > 0); return IceInternal::SocketOperationNone; } @@ -574,7 +569,7 @@ IceSSL::TransceiverI::protocol() const string IceSSL::TransceiverI::toString() const { - return _stream->toString(); + return _delegate->toString(); } string @@ -587,16 +582,19 @@ Ice::ConnectionInfoPtr IceSSL::TransceiverI::getInfo() const { NativeConnectionInfoPtr info = ICE_MAKE_SHARED(NativeConnectionInfo); - fillConnectionInfo(info, info->nativeCerts); - return info; -} - -Ice::ConnectionInfoPtr -IceSSL::TransceiverI::getWSInfo(const Ice::HeaderDict& headers) const -{ - WSSNativeConnectionInfoPtr info = ICE_MAKE_SHARED(WSSNativeConnectionInfo); - fillConnectionInfo(info, info->nativeCerts); - info->headers = headers; + info->underlying = _delegate->getInfo(); + info->incoming = _incoming; + info->adapterName = _adapterName; + info->verified = _verified; + info->nativeCerts = _nativeCerts; + for(vector<CertificatePtr>::const_iterator p = _nativeCerts.begin(); p != _nativeCerts.end(); ++p) + { + info->certs.push_back((*p)->encode()); + } + if(_ssl != 0) + { + info->cipher = SSL_get_cipher_name(_ssl); // Nothing needs to be free'd. + } return info; } @@ -608,7 +606,7 @@ IceSSL::TransceiverI::checkSendSize(const IceInternal::Buffer&) void IceSSL::TransceiverI::setBufferSize(int rcvSize, int sndSize) { - _stream->setBufferSize(rcvSize, sndSize); + _delegate->setBufferSize(rcvSize, sndSize); } int @@ -656,14 +654,15 @@ IceSSL::TransceiverI::verifyCallback(int ok, X509_STORE_CTX* c) return 1; } -IceSSL::TransceiverI::TransceiverI(const InstancePtr& instance, const IceInternal::StreamSocketPtr& stream, +IceSSL::TransceiverI::TransceiverI(const InstancePtr& instance, const IceInternal::TransceiverPtr& delegate, const string& hostOrAdapterName, bool incoming) : _instance(instance), _engine(OpenSSLEnginePtr::dynamicCast(instance->engine())), _host(incoming ? "" : hostOrAdapterName), _adapterName(incoming ? hostOrAdapterName : ""), _incoming(incoming), - _stream(stream), + _delegate(delegate), + _connected(false), _verified(false), _ssl(0) { @@ -673,30 +672,4 @@ IceSSL::TransceiverI::~TransceiverI() { } -void -IceSSL::TransceiverI::fillConnectionInfo(const ConnectionInfoPtr& info, std::vector<CertificatePtr>& nativeCerts) const -{ - IceInternal::fdToAddressAndPort(_stream->fd(), info->localAddress, info->localPort, info->remoteAddress, - info->remotePort); - if(_stream->fd() != INVALID_SOCKET) - { - info->rcvSize = IceInternal::getRecvBufferSize(_stream->fd()); - info->sndSize = IceInternal::getSendBufferSize(_stream->fd()); - } - info->adapterName = _adapterName; - info->incoming = _incoming; - info->verified = _verified; - nativeCerts = _nativeCerts; - for(vector<CertificatePtr>::const_iterator p = _nativeCerts.begin(); p != _nativeCerts.end(); ++p) - { - info->certs.push_back((*p)->encode()); - } - if(_ssl != 0) - { - info->cipher = SSL_get_cipher_name(_ssl); // Nothing needs to be free'd. - } - info->adapterName = _adapterName; - info->incoming = _incoming; -} - #endif diff --git a/cpp/src/IceSSL/OpenSSLTransceiverI.h b/cpp/src/IceSSL/OpenSSLTransceiverI.h index 8451db86b69..58459e804b9 100644 --- a/cpp/src/IceSSL/OpenSSLTransceiverI.h +++ b/cpp/src/IceSSL/OpenSSLTransceiverI.h @@ -32,7 +32,7 @@ namespace IceSSL class ConnectorI; class AcceptorI; -class TransceiverI : public IceInternal::Transceiver, public IceInternal::WSTransceiverDelegate +class TransceiverI : public IceInternal::Transceiver { public: @@ -51,7 +51,6 @@ public: virtual std::string toString() const; virtual std::string toDetailedString() const; virtual Ice::ConnectionInfoPtr getInfo() const; - virtual Ice::ConnectionInfoPtr getWSInfo(const Ice::HeaderDict&) const; virtual void checkSendSize(const IceInternal::Buffer&); virtual void setBufferSize(int rcvSize, int sndSize); @@ -59,11 +58,9 @@ public: private: - TransceiverI(const InstancePtr&, const IceInternal::StreamSocketPtr&, const std::string&, bool); + TransceiverI(const InstancePtr&, const IceInternal::TransceiverPtr&, const std::string&, bool); virtual ~TransceiverI(); - void fillConnectionInfo(const ConnectionInfoPtr&, std::vector<CertificatePtr>&) const; - friend class ConnectorI; friend class AcceptorI; @@ -72,7 +69,8 @@ private: const std::string _host; const std::string _adapterName; const bool _incoming; - const IceInternal::StreamSocketPtr _stream; + const IceInternal::TransceiverPtr _delegate; + bool _connected; bool _verified; std::vector<CertificatePtr> _nativeCerts; diff --git a/cpp/src/IceSSL/PluginI.cpp b/cpp/src/IceSSL/PluginI.cpp index 7e9fb283783..cd6bbab1f53 100644..100755 --- a/cpp/src/IceSSL/PluginI.cpp +++ b/cpp/src/IceSSL/PluginI.cpp @@ -15,6 +15,7 @@ #include <Ice/ProtocolPluginFacade.h> #include <Ice/ProtocolInstance.h> #include <Ice/LocalException.h> +#include <Ice/RegisterPlugins.h> using namespace std; using namespace Ice; @@ -23,17 +24,12 @@ using namespace IceSSL; // // Plug-in factory function. // -extern "C" -{ - -ICE_SSL_API Ice::Plugin* +extern "C" ICE_SSL_API Ice::Plugin* createIceSSL(const CommunicatorPtr& communicator, const string& /*name*/, const StringSeq& /*args*/) { return new PluginI(communicator); } -} - namespace Ice { @@ -46,6 +42,15 @@ registerIceSSL(bool loadOnInitialize) } // +// Objective-C function to allow Objective-C programs to register plugin. +// +extern "C" ICE_SSL_API void +ICEregisterIceSSL(bool loadOnInitialize) +{ + Ice::registerIceSSL(loadOnInitialize); +} + +// // Plugin implementation. // IceSSL::PluginI::PluginI(const Ice::CommunicatorPtr& com) @@ -54,6 +59,8 @@ IceSSL::PluginI::PluginI(const Ice::CommunicatorPtr& com) _engine = new SecureTransportEngine(com); #elif defined(ICE_USE_SCHANNEL) _engine = new SChannelEngine(com); +#elif defined(ICE_OS_WINRT) + _engine = new WinRTEngine(com); #else _engine = new OpenSSLEngine(com); #endif @@ -63,8 +70,31 @@ IceSSL::PluginI::PluginI(const Ice::CommunicatorPtr& com) // than in initialize, because the communicator may need to // interpret proxies before the plug-in is fully initialized. // - IceInternal::EndpointFactoryPtr sslFactory = new EndpointFactoryI(new Instance(_engine, EndpointType, "ssl")); - IceInternal::getProtocolPluginFacade(com)->addEndpointFactory(sslFactory); + IceInternal::ProtocolPluginFacadePtr pluginFacade = IceInternal::getProtocolPluginFacade(com); + + // SSL based on TCP + IceInternal::EndpointFactoryPtr tcp = pluginFacade->getEndpointFactory(TCPEndpointType); + if(tcp) + { + InstancePtr instance = new Instance(_engine, SSLEndpointType, "ssl"); + pluginFacade->addEndpointFactory(new EndpointFactoryI(instance, tcp->clone(instance, 0))); + } + + // SSL based on Bluetooth + IceInternal::EndpointFactoryPtr bluetooth = pluginFacade->getEndpointFactory(BTEndpointType); + if(bluetooth) + { + InstancePtr instance = new Instance(_engine, BTSEndpointType, "bts"); + pluginFacade->addEndpointFactory(new EndpointFactoryI(instance, bluetooth->clone(instance, 0))); + } + + // SSL based on iAP + IceInternal::EndpointFactoryPtr iap = pluginFacade->getEndpointFactory(iAPEndpointType); + if(iap) + { + InstancePtr instance = new Instance(_engine, iAPSEndpointType, "iaps"); + pluginFacade->addEndpointFactory(new EndpointFactoryI(instance, iap->clone(instance, 0))); + } } void diff --git a/cpp/src/IceSSL/PluginI.h b/cpp/src/IceSSL/PluginI.h index e0c5a48120b..ea0cf344ab4 100644 --- a/cpp/src/IceSSL/PluginI.h +++ b/cpp/src/IceSSL/PluginI.h @@ -46,6 +46,8 @@ private: SecureTransportEnginePtr _engine; #elif defined(ICE_USE_SCHANNEL) SChannelEnginePtr _engine; +#elif defined(ICE_OS_WINRT) + WinRTEnginePtr _engine; #else OpenSSLEnginePtr _engine; #endif diff --git a/cpp/src/IceSSL/RFC2253.cpp b/cpp/src/IceSSL/RFC2253.cpp index 7b46682f3c2..e4c57add13a 100644 --- a/cpp/src/IceSSL/RFC2253.cpp +++ b/cpp/src/IceSSL/RFC2253.cpp @@ -271,7 +271,7 @@ parseAttributeType(const string& data, size_t& pos) // // Here we must also check for "oid." and "OID." before parsing // according to the ALPHA KEYCHAR* rule. - // + // // First the OID case. // if(IceUtilInternal::isDigit(data[pos]) || @@ -318,7 +318,7 @@ parseAttributeType(const string& data, size_t& pos) result += data[pos]; ++pos; // 1* KEYCHAR - while(pos < data.size() && + while(pos < data.size() && (IceUtilInternal::isAlpha(data[pos]) || IceUtilInternal::isDigit(data[pos]) || data[pos] == '-')) { result += data[pos]; @@ -448,7 +448,7 @@ parsePair(const string& data, size_t& pos) } return parseHexPair(data, pos, false); } - + // // RFC 2253 // hexpair = hexchar hexchar diff --git a/cpp/src/IceSSL/SChannelTransceiverI.cpp b/cpp/src/IceSSL/SChannelTransceiverI.cpp index b5eca20d632..d7555d545a9 100644 --- a/cpp/src/IceSSL/SChannelTransceiverI.cpp +++ b/cpp/src/IceSSL/SChannelTransceiverI.cpp @@ -208,7 +208,7 @@ getSecBufferWithType(const SecBufferDesc& desc, ULONG bufferType) IceInternal::NativeInfoPtr IceSSL::TransceiverI::getNativeInfo() { - return _stream; + return _delegate->getNativeInfo(); } IceInternal::SocketOperation @@ -624,13 +624,17 @@ IceSSL::TransceiverI::encryptMessage(IceInternal::Buffer& buffer) IceInternal::SocketOperation IceSSL::TransceiverI::initialize(IceInternal::Buffer& readBuffer, IceInternal::Buffer& writeBuffer) { - IceInternal::SocketOperation op = _stream->connect(readBuffer, writeBuffer); - if(op != IceInternal::SocketOperationNone) + if(_state == StateNotInitialized) { - return op; + IceInternal::SocketOperation op = _delegate->initialize(readBuffer, writeBuffer); + if(op != IceInternal::SocketOperationNone) + { + return op; + } + _state = StateHandshakeNotStarted; } - op = sslHandshake(); + IceInternal::SocketOperation op = sslHandshake(); if(op != IceInternal::SocketOperationNone) { return op; @@ -715,7 +719,7 @@ IceSSL::TransceiverI::initialize(IceInternal::Buffer& readBuffer, IceInternal::B } } - _engine->verifyPeer(_stream->fd(), _host, ICE_DYNAMIC_CAST(NativeConnectionInfo, getInfo())); + _engine->verifyPeer(_host, ICE_DYNAMIC_CAST(NativeConnectionInfo, getInfo()), toString()); _state = StateHandshakeComplete; if(_instance->engine()->securityTraceLevel() >= 1) @@ -746,8 +750,8 @@ IceSSL::TransceiverI::initialize(IceInternal::Buffer& readBuffer, IceInternal::B } out << toString(); } - _stream->ready(IceInternal::SocketOperationRead, - !_readUnprocessed.b.empty() || _readBuffer.i != _readBuffer.b.begin()); + _delegate->getNativeInfo()->ready(IceInternal::SocketOperationRead, + !_readUnprocessed.b.empty() || _readBuffer.i != _readBuffer.b.begin()); return IceInternal::SocketOperationNone; } @@ -778,7 +782,7 @@ IceSSL::TransceiverI::close() _credentialsInitialized = false; } - _stream->close(); + _delegate->close(); // // Clear the buffers now instead of waiting for destruction. @@ -791,9 +795,9 @@ IceSSL::TransceiverI::close() IceInternal::SocketOperation IceSSL::TransceiverI::write(IceInternal::Buffer& buf) { - if(!_stream->isConnected()) + if(_state == StateNotInitialized) { - return _stream->write(buf); + return _delegate->write(buf); } if(buf.i == buf.b.end()) @@ -826,9 +830,9 @@ IceSSL::TransceiverI::write(IceInternal::Buffer& buf) IceInternal::SocketOperation IceSSL::TransceiverI::read(IceInternal::Buffer& buf) { - if(!_stream->isConnected()) + if(_state == StateNotInitialized) { - return _stream->read(buf); + return _delegate->read(buf); } if(buf.i == buf.b.end()) @@ -837,7 +841,7 @@ IceSSL::TransceiverI::read(IceInternal::Buffer& buf) } assert(_state == StateHandshakeComplete); - _stream->ready(IceInternal::SocketOperationRead, false); + _delegate->getNativeInfo()->ready(IceInternal::SocketOperationRead, false); while(buf.i != buf.b.end()) { if(_readUnprocessed.b.empty() && _readBuffer.i == _readBuffer.b.begin() && !readRaw(_readBuffer)) @@ -857,8 +861,8 @@ IceSSL::TransceiverI::read(IceInternal::Buffer& buf) buf.i += decrypted; } - _stream->ready(IceInternal::SocketOperationRead, - !_readUnprocessed.b.empty() || _readBuffer.i != _readBuffer.b.begin()); + _delegate->getNativeInfo()->ready(IceInternal::SocketOperationRead, + !_readUnprocessed.b.empty() || _readBuffer.i != _readBuffer.b.begin()); return IceInternal::SocketOperationNone; } @@ -867,9 +871,9 @@ IceSSL::TransceiverI::read(IceInternal::Buffer& buf) bool IceSSL::TransceiverI::startWrite(IceInternal::Buffer& buffer) { - if(!_stream->isConnected()) + if(_state == StateNotInitialized) { - return _stream->startWrite(buffer); + return _delegate->startWrite(buffer); } if(_state == StateHandshakeComplete && _bufferedW == 0) @@ -878,19 +882,19 @@ IceSSL::TransceiverI::startWrite(IceInternal::Buffer& buffer) _bufferedW = encryptMessage(buffer); } - return _stream->startWrite(_writeBuffer); + return _delegate->startWrite(_writeBuffer) && _bufferedW == (buffer.b.end() - buffer.i); } void IceSSL::TransceiverI::finishWrite(IceInternal::Buffer& buf) { - if(!_stream->isConnected()) + if(_state == StateNotInitialized) { - _stream->finishWrite(buf); + _delegate->finishWrite(buf); return; } - _stream->finishWrite(_writeBuffer); + _delegate->finishWrite(_writeBuffer); if(_writeBuffer.i != _writeBuffer.b.end()) { return; // We're not finished yet with writing the write buffer. @@ -906,36 +910,36 @@ IceSSL::TransceiverI::finishWrite(IceInternal::Buffer& buf) void IceSSL::TransceiverI::startRead(IceInternal::Buffer& buffer) { - if(!_stream->isConnected()) + if(_state == StateNotInitialized) { - _stream->startRead(buffer); + _delegate->startRead(buffer); return; } - _stream->startRead(_readBuffer); + _delegate->startRead(_readBuffer); } void IceSSL::TransceiverI::finishRead(IceInternal::Buffer& buf) { - if(!_stream->isConnected()) + if(_state == StateNotInitialized) { - _stream->finishRead(buf); + _delegate->finishRead(buf); return; } - _stream->finishRead(_readBuffer); + _delegate->finishRead(_readBuffer); if(_state == StateHandshakeComplete) { size_t decrypted = decryptMessage(buf); if(decrypted > 0) { buf.i += decrypted; - _stream->ready(IceInternal::SocketOperationRead, - !_readUnprocessed.b.empty() || _readBuffer.i != _readBuffer.b.begin()); + _delegate->getNativeInfo()->ready(IceInternal::SocketOperationRead, + !_readUnprocessed.b.empty() || _readBuffer.i != _readBuffer.b.begin()); } else { - _stream->ready(IceInternal::SocketOperationRead, false); + _delegate->getNativeInfo()->ready(IceInternal::SocketOperationRead, false); } } } @@ -950,7 +954,7 @@ IceSSL::TransceiverI::protocol() const string IceSSL::TransceiverI::toString() const { - return _stream->toString(); + return _delegate->toString(); } string @@ -963,65 +967,10 @@ Ice::ConnectionInfoPtr IceSSL::TransceiverI::getInfo() const { NativeConnectionInfoPtr info = ICE_MAKE_SHARED(NativeConnectionInfo); - fillConnectionInfo(info, info->nativeCerts); - return info; -} - -Ice::ConnectionInfoPtr -IceSSL::TransceiverI::getWSInfo(const Ice::HeaderDict& headers) const -{ - WSSNativeConnectionInfoPtr info = ICE_MAKE_SHARED(WSSNativeConnectionInfo); - fillConnectionInfo(info, info->nativeCerts); - info->headers = headers; - return info; -} - -void -IceSSL::TransceiverI::checkSendSize(const IceInternal::Buffer&) -{ -} - -void -IceSSL::TransceiverI::setBufferSize(int rcvSize, int sndSize) -{ - _stream->setBufferSize(rcvSize, sndSize); -} - -IceSSL::TransceiverI::TransceiverI(const InstancePtr& instance, - const IceInternal::StreamSocketPtr& stream, - const string& hostOrAdapterName, - bool incoming) : - _instance(instance), - _engine(SChannelEnginePtr::dynamicCast(instance->engine())), - _host(incoming ? "" : hostOrAdapterName), - _adapterName(incoming ? hostOrAdapterName : ""), - _incoming(incoming), - _stream(stream), - _state(StateHandshakeNotStarted), - _bufferedW(0), - _sslInitialized(false), - _credentialsInitialized(false), - _verified(false) -{ -} - -IceSSL::TransceiverI::~TransceiverI() -{ -} - -void -IceSSL::TransceiverI::fillConnectionInfo(const ConnectionInfoPtr& info, vector<CertificatePtr>& nativeCerts) const -{ - IceInternal::fdToAddressAndPort(_stream->fd(), info->localAddress, info->localPort, info->remoteAddress, - info->remotePort); - if(_stream->fd() != INVALID_SOCKET) - { - info->rcvSize = IceInternal::getRecvBufferSize(_stream->fd()); - info->sndSize = IceInternal::getSendBufferSize(_stream->fd()); - } - + info->underlying = _delegate->getInfo(); + info->incoming = _incoming; + info->adapterName = _adapterName; info->verified = _verified; - if(_sslInitialized) { CtxtHandle* ssl = const_cast<CtxtHandle*>(&_ssl); @@ -1056,7 +1005,7 @@ IceSSL::TransceiverI::fillConnectionInfo(const ConnectionInfoPtr& info, vector<C } CertificatePtr certificate = ICE_MAKE_SHARED(Certificate, cc); - nativeCerts.push_back(certificate); + info->nativeCerts.push_back(certificate); info->certs.push_back(certificate->encode()); } CertFreeCertificateChain(certChain); @@ -1080,24 +1029,53 @@ IceSSL::TransceiverI::fillConnectionInfo(const ConnectionInfoPtr& info, vector<C IceUtilInternal::lastErrorToString()); } } + return info; +} - info->adapterName = _adapterName; - info->incoming = _incoming; +void +IceSSL::TransceiverI::checkSendSize(const IceInternal::Buffer&) +{ +} + +void +IceSSL::TransceiverI::setBufferSize(int rcvSize, int sndSize) +{ + _delegate->setBufferSize(rcvSize, sndSize); +} + +IceSSL::TransceiverI::TransceiverI(const InstancePtr& instance, + const IceInternal::TransceiverPtr& delegate, + const string& hostOrAdapterName, + bool incoming) : + _instance(instance), + _engine(SChannelEnginePtr::dynamicCast(instance->engine())), + _host(incoming ? "" : hostOrAdapterName), + _adapterName(incoming ? hostOrAdapterName : ""), + _incoming(incoming), + _delegate(delegate), + _state(StateNotInitialized), + _bufferedW(0), + _sslInitialized(false), + _credentialsInitialized(false), + _verified(false) +{ +} +IceSSL::TransceiverI::~TransceiverI() +{ } bool IceSSL::TransceiverI::writeRaw(IceInternal::Buffer& buf) { - ssize_t ret = _stream->write(reinterpret_cast<const char*>(&*buf.i), buf.b.end() - buf.i); - buf.i += ret; + _delegate->write(buf); return buf.i == buf.b.end(); } bool IceSSL::TransceiverI::readRaw(IceInternal::Buffer& buf) { - ssize_t ret = _stream->read(reinterpret_cast<char*>(&*buf.i), buf.b.end() - buf.i); - buf.i += ret; - return ret > 0; + IceInternal::Buffer::Container::iterator p = buf.i; + _delegate->read(buf); + return buf.i != p; } #endif diff --git a/cpp/src/IceSSL/SChannelTransceiverI.h b/cpp/src/IceSSL/SChannelTransceiverI.h index b9d96b47eea..dc9d8030b61 100644 --- a/cpp/src/IceSSL/SChannelTransceiverI.h +++ b/cpp/src/IceSSL/SChannelTransceiverI.h @@ -43,7 +43,7 @@ namespace IceSSL class ConnectorI; class AcceptorI; -class TransceiverI : public IceInternal::Transceiver, public IceInternal::WSTransceiverDelegate +class TransceiverI : public IceInternal::Transceiver { public: @@ -68,17 +68,14 @@ public: virtual std::string toString() const; virtual std::string toDetailedString() const; virtual Ice::ConnectionInfoPtr getInfo() const; - virtual Ice::ConnectionInfoPtr getWSInfo(const Ice::HeaderDict&) const; virtual void checkSendSize(const IceInternal::Buffer&); virtual void setBufferSize(int rcvSize, int sndSize); private: - TransceiverI(const InstancePtr&, const IceInternal::StreamSocketPtr&, const std::string&, bool); + TransceiverI(const InstancePtr&, const IceInternal::TransceiverPtr&, const std::string&, bool); virtual ~TransceiverI(); - void fillConnectionInfo(const ConnectionInfoPtr&, std::vector<CertificatePtr>&) const; - IceInternal::SocketOperation sslHandshake(); size_t decryptMessage(IceInternal::Buffer&); @@ -92,6 +89,7 @@ private: enum State { + StateNotInitialized, StateHandshakeNotStarted, StateHandshakeReadContinue, StateHandshakeWriteContinue, @@ -103,7 +101,7 @@ private: const std::string _host; const std::string _adapterName; const bool _incoming; - const IceInternal::StreamSocketPtr _stream; + const IceInternal::TransceiverPtr _delegate; State _state; // diff --git a/cpp/src/IceSSL/SSLEngine.cpp b/cpp/src/IceSSL/SSLEngine.cpp index 31bc4d54e3d..ed286df2b5b 100644 --- a/cpp/src/IceSSL/SSLEngine.cpp +++ b/cpp/src/IceSSL/SSLEngine.cpp @@ -115,23 +115,24 @@ IceSSL::SSLEngine::initialize() // VerifyPeer determines whether certificate validation failures abort a connection. // _verifyPeer = properties->getPropertyAsIntWithDefault(propPrefix + "VerifyPeer", 2); - + if(_verifyPeer < 0 || _verifyPeer > 2) { PluginInitializationException ex(__FILE__, __LINE__); ex.reason = "IceSSL: invalid value for " + propPrefix + "VerifyPeer"; throw ex; } - + _securityTraceLevel = properties->getPropertyAsInt("IceSSL.Trace.Security"); _securityTraceCategory = "Security"; } void -IceSSL::SSLEngine::verifyPeer(SOCKET fd, const string& address, const NativeConnectionInfoPtr& info) +IceSSL::SSLEngine::verifyPeer(const string& address, const NativeConnectionInfoPtr& info, const string& desc) { const CertificateVerifierPtr verifier = getCertificateVerifier(); - + +#if !defined(ICE_USE_SECURE_TRANSPORT_IOS) // // For an outgoing connection, we compare the proxy address (if any) against // fields in the server's certificate (if any). @@ -248,6 +249,7 @@ IceSSL::SSLEngine::verifyPeer(SOCKET fd, const string& address, const NativeConn } } } +#endif if(_verifyDepthMax > 0 && static_cast<int>(info->certs.size()) > _verifyDepthMax) { @@ -258,19 +260,19 @@ IceSSL::SSLEngine::verifyPeer(SOCKET fd, const string& address, const NativeConn string msg = ostr.str(); if(_securityTraceLevel >= 1) { - _logger->trace(_securityTraceCategory, msg + "\n" + IceInternal::fdToString(fd)); + _logger->trace(_securityTraceCategory, msg + "\n" + desc); } SecurityException ex(__FILE__, __LINE__); ex.reason = msg; throw ex; } - if(!_trustManager->verify(info)) + if(!_trustManager->verify(info, desc)) { string msg = string(info->incoming ? "incoming" : "outgoing") + " connection rejected by trust manager"; if(_securityTraceLevel >= 1) { - _logger->trace(_securityTraceCategory, msg + "\n" + IceInternal::fdToString(fd)); + _logger->trace(_securityTraceCategory, msg + "\n" + desc); } SecurityException ex(__FILE__, __LINE__); ex.reason = msg; @@ -282,7 +284,7 @@ IceSSL::SSLEngine::verifyPeer(SOCKET fd, const string& address, const NativeConn string msg = string(info->incoming ? "incoming" : "outgoing") + " connection rejected by certificate verifier"; if(_securityTraceLevel >= 1) { - _logger->trace(_securityTraceCategory, msg + "\n" + IceInternal::fdToString(fd)); + _logger->trace(_securityTraceCategory, msg + "\n" + desc); } SecurityException ex(__FILE__, __LINE__); ex.reason = msg; diff --git a/cpp/src/IceSSL/SSLEngine.h b/cpp/src/IceSSL/SSLEngine.h index 08b79e85bd5..25748c71c78 100644 --- a/cpp/src/IceSSL/SSLEngine.h +++ b/cpp/src/IceSSL/SSLEngine.h @@ -22,6 +22,7 @@ #if defined(ICE_USE_SECURE_TRANSPORT) # include <Security/Security.h> +# include <Security/SecureTransport.h> #elif defined(ICE_USE_SCHANNEL) // @@ -72,7 +73,7 @@ public: // // Verify peer certificate // - void verifyPeer(SOCKET, const std::string&, const NativeConnectionInfoPtr&); + void verifyPeer(const std::string&, const NativeConnectionInfoPtr&, const std::string&); CertificateVerifierPtr getCertificateVerifier() const; PasswordPromptPtr getPasswordPrompt() const; @@ -80,6 +81,7 @@ public: std::string getPassword() const; void setPassword(const std::string& password); + bool getCheckCertName() const { return _checkCertName; } int getVerifyPeer() const { return _verifyPeer; } int securityTraceLevel() const { return _securityTraceLevel; } std::string securityTraceCategory() const { return _securityTraceCategory; } @@ -120,7 +122,6 @@ public: private: void parseCiphers(const std::string&); - SecKeychainRef openKeychain(); bool _initialized; UniqueRef<CFArrayRef> _certificateAuthorities; @@ -131,8 +132,9 @@ private: std::string _defaultDir; +#if TARGET_OS_IPHONE==0 std::vector<char> _dhParams; - +#endif std::vector<SSLCipherSuite> _ciphers; IceUtil::Mutex _mutex; }; @@ -179,6 +181,7 @@ private: # endif #endif + class SChannelEngine : public SSLEngine { public: @@ -219,7 +222,22 @@ private: HCERTCHAINENGINE _chainEngine; std::vector<ALG_ID> _ciphers; }; + +#elif defined(ICE_OS_WINRT) + +class WinRTEngine : public SSLEngine +{ +public: + + WinRTEngine(const Ice::CommunicatorPtr&); + + virtual void initialize(); + virtual bool initialized() const; + virtual void destroy(); +}; + #else // OpenSSL + class OpenSSLEngine : public SSLEngine { public: diff --git a/cpp/src/IceSSL/SSLEngineF.h b/cpp/src/IceSSL/SSLEngineF.h index 6d9c7a1e284..61656a11d2a 100644 --- a/cpp/src/IceSSL/SSLEngineF.h +++ b/cpp/src/IceSSL/SSLEngineF.h @@ -19,20 +19,24 @@ namespace IceSSL { class SSLEngine; -ICE_SSL_API IceUtil::Shared* upCast(IceSSL::SSLEngine*); +ICE_SSL_API IceUtil::Shared* upCast(SSLEngine*); typedef IceInternal::Handle<SSLEngine> SSLEnginePtr; #if defined(ICE_USE_SECURE_TRANSPORT) class SecureTransportEngine; -ICE_SSL_API IceUtil::Shared* upCast(IceSSL::SecureTransportEngine*); +ICE_SSL_API IceUtil::Shared* upCast(SecureTransportEngine*); typedef IceInternal::Handle<SecureTransportEngine> SecureTransportEnginePtr; #elif defined(ICE_USE_SCHANNEL) class SChannelEngine; -ICE_SSL_API IceUtil::Shared* upCast(IceSSL::SChannelEngine*); +ICE_SSL_API IceUtil::Shared* upCast(SChannelEngine*); typedef IceInternal::Handle<SChannelEngine> SChannelEnginePtr; +#elif defined(ICE_OS_WINRT) +class WinRTEngine; +ICE_SSL_API IceUtil::Shared* upCast(WinRTEngine*); +typedef IceInternal::Handle<WinRTEngine> WinRTEnginePtr; #else // OpenSSL class OpenSSLEngine; -ICE_SSL_API IceUtil::Shared* upCast(IceSSL::OpenSSLEngine*); +ICE_SSL_API IceUtil::Shared* upCast(OpenSSLEngine*); typedef IceInternal::Handle<OpenSSLEngine> OpenSSLEnginePtr; #endif diff --git a/cpp/src/IceSSL/SecureTransportEngine.cpp b/cpp/src/IceSSL/SecureTransportEngine.cpp index 00cb59d4c83..1876477794c 100644 --- a/cpp/src/IceSSL/SecureTransportEngine.cpp +++ b/cpp/src/IceSSL/SecureTransportEngine.cpp @@ -858,6 +858,9 @@ IceSSL::SecureTransportEngine::initialize() string certFile = properties->getProperty("IceSSL.CertFile"); string keyFile = properties->getProperty("IceSSL.KeyFile"); string findCert = properties->getProperty("IceSSL.FindCert"); + string keychain = properties->getProperty("IceSSL.Keychain"); + string keychainPassword = properties->getProperty("IceSSL.KeychainPassword"); + if(!certFile.empty()) { vector<string> files; @@ -903,10 +906,10 @@ IceSSL::SecureTransportEngine::initialize() keyFile = resolved; } - UniqueRef<SecKeychainRef> kc(openKeychain()); try { - _chain.reset(loadCertificateChain(file, keyFile, kc.get(), password, passwordPrompt, passwordRetryMax)); + _chain.reset(loadCertificateChain(file, keyFile, keychain, keychainPassword, password, passwordPrompt, + passwordRetryMax)); break; } catch(const CertificateReadException& ce) @@ -924,57 +927,13 @@ IceSSL::SecureTransportEngine::initialize() } else if(!findCert.empty()) { - UniqueRef<SecKeychainRef> kc(openKeychain()); - UniqueRef<SecCertificateRef> cert(findCertificate(kc.get(), findCert)); - - // - // Retrieve the certificate chain - // - UniqueRef<SecPolicyRef> policy(SecPolicyCreateSSL(true, 0)); - SecTrustRef trust = 0; - OSStatus err = SecTrustCreateWithCertificates((CFArrayRef)cert.get(), policy.get(), &trust); - if(err || !trust) - { - throw PluginInitializationException(__FILE__, __LINE__, - "IceSSL: error creating trust object" + - (err ? ":\n" + errorToString(err) : "")); - } - UniqueRef<SecTrustRef> v(trust); - - SecTrustResultType trustResult; - if((err = SecTrustEvaluate(trust, &trustResult))) - { - throw PluginInitializationException(__FILE__, __LINE__, - "IceSSL: error evaluating trust:\n" + errorToString(err)); - } - - int chainLength = SecTrustGetCertificateCount(trust); - CFMutableArrayRef items = CFArrayCreateMutable(kCFAllocatorDefault, chainLength, &kCFTypeArrayCallBacks); - for(int i = 0; i < chainLength; ++i) - { - CFArrayAppendValue(items, SecTrustGetCertificateAtIndex(trust, i)); - } - - // - // Replace the first certificate in the chain with the - // identity. - // - SecIdentityRef identity; - err = SecIdentityCreateWithCertificate(kc.get(), cert.get(), &identity); - if(err != noErr) - { - ostringstream os; - os << "IceSSL: couldn't create identity for certificate found in the keychain:\n" << errorToString(err); - throw PluginInitializationException(__FILE__, __LINE__, os.str()); - } - CFArraySetValueAtIndex(items, 0, identity); - CFRelease(identity); - _chain.reset(items); + _chain.reset(findCertificateChain(keychain, keychainPassword, findCert)); } // // DiffieHellmanParams in DER format. // +#if defined(ICE_USE_SECURE_TRANSPORT_MACOS) string dhFile = properties->getProperty("IceSSL.DHParams"); if(!dhFile.empty()) { @@ -986,6 +945,7 @@ IceSSL::SecureTransportEngine::initialize() readFile(resolved, _dhParams); } +#endif // // Establish the cipher list. @@ -1086,6 +1046,7 @@ IceSSL::SecureTransportEngine::newContext(bool incoming) } } +#if defined(ICE_USE_SECURE_TRANSPORT_MACOS) if(!_dhParams.empty()) { if((err = SSLSetDiffieHellmanParams(ssl, &_dhParams[0], _dhParams.size()))) @@ -1094,6 +1055,7 @@ IceSSL::SecureTransportEngine::newContext(bool incoming) "IceSSL: unable to create the trust object:\n" + errorToString(err)); } } +#endif } if(_chain && (err = SSLSetCertificate(ssl, _chain.get()))) @@ -1318,92 +1280,5 @@ IceSSL::SecureTransportEngine::parseCiphers(const string& ciphers) } } -SecKeychainRef -SecureTransportEngine::openKeychain() -{ - const PropertiesPtr properties = communicator()->getProperties(); - - // - // Open the application KeyChain or create it if the keychain doesn't exists - // - string keychainPath = properties->getProperty("IceSSL.Keychain"); - string keychainPassword = properties->getProperty("IceSSL.KeychainPassword"); - - SecKeychainRef keychain = 0; - OSStatus err = 0; - if(keychainPath.empty()) - { - if((err = SecKeychainCopyDefault(&keychain))) - { - throw PluginInitializationException(__FILE__, __LINE__, - "IceSSL: unable to retrieve default keychain:\n" + errorToString(err)); - } - } - else - { - // - // KeyChain path is relative to the current working directory. - // - if(!IceUtilInternal::isAbsolutePath(keychainPath)) - { - string cwd; - if(IceUtilInternal::getcwd(cwd) == 0) - { - keychainPath = string(cwd) + '/' + keychainPath; - } - } - - if((err = SecKeychainOpen(keychainPath.c_str(), &keychain))) - { - throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: unable to open keychain: `" + - keychainPath + "'\n" + errorToString(err)); - } - } - - UniqueRef<SecKeychainRef> k(keychain); - - SecKeychainStatus status; - err = SecKeychainGetStatus(keychain, &status); - if(err == noErr) - { - const char* pass = keychainPassword.empty() ? 0 : keychainPassword.c_str(); - if((err = SecKeychainUnlock(keychain, keychainPassword.size(), pass, pass != 0))) - { - throw PluginInitializationException(__FILE__, __LINE__, - "IceSSL: unable to unlock keychain:\n" + errorToString(err)); - } - } - else if(err == errSecNoSuchKeychain) - { - const char* pass = keychainPassword.empty() ? 0 : keychainPassword.c_str(); - if((err = SecKeychainCreate(keychainPath.c_str(), keychainPassword.size(), pass, pass == 0, 0, &keychain))) - { - throw PluginInitializationException(__FILE__, __LINE__, - "IceSSL: unable to create keychain:\n" + errorToString(err)); - } - k.reset(keychain); - } - else - { - throw PluginInitializationException(__FILE__, __LINE__, - "IceSSL: unable to open keychain:\n" + errorToString(err)); - } - - // - // Set keychain settings to avoid keychain lock. - // - SecKeychainSettings settings; - settings.version = SEC_KEYCHAIN_SETTINGS_VERS1; - settings.lockOnSleep = FALSE; - settings.useLockInterval = FALSE; - settings.lockInterval = INT_MAX; - if((err = SecKeychainSetSettings(keychain, &settings))) - { - throw PluginInitializationException(__FILE__, __LINE__, - "IceSSL: error setting keychain settings:\n" + errorToString(err)); - } - - return k.release(); -} #endif diff --git a/cpp/src/IceSSL/SecureTransportTransceiverI.cpp b/cpp/src/IceSSL/SecureTransportTransceiverI.cpp index b043ef19713..f407e008913 100644 --- a/cpp/src/IceSSL/SecureTransportTransceiverI.cpp +++ b/cpp/src/IceSSL/SecureTransportTransceiverI.cpp @@ -96,7 +96,8 @@ socketRead(SSLConnectionRef connection, void* data, size_t* length) } bool -checkTrustResult(SecTrustRef trust, const SecureTransportEnginePtr& engine, const InstancePtr& instance) +checkTrustResult(SecTrustRef trust, const SecureTransportEnginePtr& engine, const InstancePtr& instance, + const string& host) { OSStatus err = noErr; SecTrustResultType trustResult = kSecTrustResultOtherError; @@ -115,6 +116,28 @@ checkTrustResult(SecTrustRef trust, const SecureTransportEnginePtr& engine, cons throw SecurityException(__FILE__, __LINE__, "IceSSL: handshake failure:\n" + errorToString(err)); } +#if defined(ICE_USE_SECURE_TRANSPORT_IOS) + if(engine->getCheckCertName() && !host.empty()) + { + // + // Add SSL trust policy if we need to check the certificate name. + // + UniqueRef<SecPolicyRef> policy(SecPolicyCreateSSL(false, toCFString(host))); + CFArrayRef policies; + if((err = SecTrustCopyPolicies(trust, &policies))) + { + throw SecurityException(__FILE__, __LINE__, "IceSSL: handshake failure:\n" + errorToString(err)); + } + UniqueRef<CFMutableArrayRef> newPolicies(CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, policies)); + CFRelease(policies); + CFArrayAppendValue(newPolicies.get(), policy.release()); + if((err = SecTrustSetPolicies(trust, newPolicies.release()))) + { + throw SecurityException(__FILE__, __LINE__, "IceSSL: handshake failure:\n" + errorToString(err)); + } + } +#endif + // // Evaluate the trust // @@ -171,18 +194,29 @@ checkTrustResult(SecTrustRef trust, const SecureTransportEnginePtr& engine, cons IceInternal::NativeInfoPtr IceSSL::TransceiverI::getNativeInfo() { - return _stream; + return _delegate->getNativeInfo(); } IceInternal::SocketOperation IceSSL::TransceiverI::initialize(IceInternal::Buffer& readBuffer, IceInternal::Buffer& writeBuffer) { - IceInternal::SocketOperation status = _stream->connect(readBuffer, writeBuffer); - if(status != IceInternal::SocketOperationNone) + if(!_connected) { - return status; + IceInternal::SocketOperation status = _delegate->initialize(readBuffer, writeBuffer); + if(status != IceInternal::SocketOperationNone) + { + return status; + } + _connected = true; } + // + // Limit the size of packets passed to SSLWrite/SSLRead to avoid + // blocking and holding too much memory. + // + _maxSendPacketSize = std::max(512, IceInternal::getSendBufferSize(_delegate->getNativeInfo()->fd())); + _maxRecvPacketSize = std::max(512, IceInternal::getRecvBufferSize(_delegate->getNativeInfo()->fd())); + OSStatus err = 0; if(!_ssl) { @@ -237,7 +271,7 @@ IceSSL::TransceiverI::initialize(IceInternal::Buffer& readBuffer, IceInternal::B } if(err == noErr) { - _verified = checkTrustResult(_trust, _engine, _instance); + _verified = checkTrustResult(_trust, _engine, _instance, _host); continue; // Call SSLHandshake to resume the handsake. } // Let it fall through, this will raise a SecurityException with the SSLCopyPeerTrust error. @@ -247,18 +281,12 @@ IceSSL::TransceiverI::initialize(IceInternal::Buffer& readBuffer, IceInternal::B throw ConnectionLostException(__FILE__, __LINE__, 0); } - IceInternal::Address remoteAddr; - string desc = "<not available>"; - if(IceInternal::fdToRemoteAddress(_stream->fd(), remoteAddr)) - { - desc = IceInternal::addrToString(remoteAddr); - } ostringstream os; os << "IceSSL: ssl error occurred for new " << (_incoming ? "incoming" : "outgoing") << " connection:\n" - << "remote address = " << desc << "\n" << errorToString(err); + << _delegate->toString() << "\n" << errorToString(err); throw ProtocolException(__FILE__, __LINE__, os.str()); } - _engine->verifyPeer(_stream->fd(), _host, ICE_DYNAMIC_CAST(NativeConnectionInfo, getInfo())); + _engine->verifyPeer(_host, ICE_DYNAMIC_CAST(NativeConnectionInfo, getInfo()), toString()); if(_instance->engine()->securityTraceLevel() >= 1) { @@ -317,15 +345,15 @@ IceSSL::TransceiverI::close() _ssl = 0; } - _stream->close(); + _delegate->close(); } IceInternal::SocketOperation IceSSL::TransceiverI::write(IceInternal::Buffer& buf) { - if(!_stream->isConnected()) + if(!_connected) { - return _stream->write(buf); + return _delegate->write(buf); } if(buf.i == buf.b.end()) @@ -402,9 +430,9 @@ IceSSL::TransceiverI::write(IceInternal::Buffer& buf) IceInternal::SocketOperation IceSSL::TransceiverI::read(IceInternal::Buffer& buf) { - if(!_stream->isConnected()) + if(!_connected) { - return _stream->read(buf); + return _delegate->read(buf); } if(buf.i == buf.b.end()) @@ -412,7 +440,7 @@ IceSSL::TransceiverI::read(IceInternal::Buffer& buf) return IceInternal::SocketOperationNone; } - _stream->ready(IceInternal::SocketOperationRead, false); + _delegate->getNativeInfo()->ready(IceInternal::SocketOperationRead, false); size_t packetSize = std::min(static_cast<size_t>(buf.b.end() - buf.i), _maxRecvPacketSize); while(buf.i != buf.b.end()) @@ -471,7 +499,7 @@ IceSSL::TransceiverI::read(IceInternal::Buffer& buf) errno = err; throw SocketException(__FILE__, __LINE__, IceInternal::getSocketErrno()); } - _stream->ready(IceInternal::SocketOperationRead, buffered > 0); + _delegate->getNativeInfo()->ready(IceInternal::SocketOperationRead, buffered > 0); return IceInternal::SocketOperationNone; } @@ -484,7 +512,7 @@ IceSSL::TransceiverI::protocol() const string IceSSL::TransceiverI::toString() const { - return _stream->toString(); + return _delegate->toString(); } string @@ -497,16 +525,30 @@ Ice::ConnectionInfoPtr IceSSL::TransceiverI::getInfo() const { NativeConnectionInfoPtr info = ICE_MAKE_SHARED(NativeConnectionInfo); - fillConnectionInfo(info, info->nativeCerts); - return info; -} + info->underlying = _delegate->getInfo(); + info->incoming = _incoming; + info->adapterName = _adapterName; + if(_ssl) + { + for(int i = 0, count = SecTrustGetCertificateCount(_trust); i < count; ++i) + { + SecCertificateRef cert = SecTrustGetCertificateAtIndex(_trust, i); + CFRetain(cert); -Ice::ConnectionInfoPtr -IceSSL::TransceiverI::getWSInfo(const Ice::HeaderDict& headers) const -{ - WSSNativeConnectionInfoPtr info = ICE_MAKE_SHARED(WSSNativeConnectionInfo); - fillConnectionInfo(info, info->nativeCerts); - info->headers = headers; + CertificatePtr certificate = ICE_MAKE_SHARED(Certificate, cert); + info->nativeCerts.push_back(certificate); + info->certs.push_back(certificate->encode()); + } + + SSLCipherSuite cipher; + SSLGetNegotiatedCipher(_ssl, &cipher); + info->cipher = _engine->getCipherName(cipher); + info->verified = _verified; + } + else + { + info->verified = false; + } return info; } @@ -518,11 +560,11 @@ IceSSL::TransceiverI::checkSendSize(const IceInternal::Buffer&) void IceSSL::TransceiverI::setBufferSize(int rcvSize, int sndSize) { - _stream->setBufferSize(rcvSize, sndSize); + _delegate->setBufferSize(rcvSize, sndSize); } IceSSL::TransceiverI::TransceiverI(const InstancePtr& instance, - const IceInternal::StreamSocketPtr& stream, + const IceInternal::TransceiverPtr& delegate, const string& hostOrAdapterName, bool incoming) : _instance(instance), @@ -530,61 +572,19 @@ IceSSL::TransceiverI::TransceiverI(const InstancePtr& instance, _host(incoming ? "" : hostOrAdapterName), _adapterName(incoming ? hostOrAdapterName : ""), _incoming(incoming), - _stream(stream), + _delegate(delegate), _ssl(0), _trust(0), + _connected(false), _verified(false), _buffered(0) { - // - // Limit the size of packets passed to SSLWrite/SSLRead to avoid - // blocking and holding too much memory. - // - _maxSendPacketSize = std::max(512, IceInternal::getSendBufferSize(_stream->fd())); - _maxRecvPacketSize = std::max(512, IceInternal::getRecvBufferSize(_stream->fd())); } IceSSL::TransceiverI::~TransceiverI() { } -void -IceSSL::TransceiverI::fillConnectionInfo(const ConnectionInfoPtr& info, std::vector<CertificatePtr>& nativeCerts) const -{ - IceInternal::fdToAddressAndPort(_stream->fd(), info->localAddress, info->localPort, info->remoteAddress, - info->remotePort); - if(_stream->fd() != INVALID_SOCKET) - { - info->rcvSize = IceInternal::getRecvBufferSize(_stream->fd()); - info->sndSize = IceInternal::getSendBufferSize(_stream->fd()); - } - - if(_ssl) - { - for(int i = 0, count = SecTrustGetCertificateCount(_trust); i < count; ++i) - { - SecCertificateRef cert = SecTrustGetCertificateAtIndex(_trust, i); - CFRetain(cert); - - CertificatePtr certificate = ICE_MAKE_SHARED(Certificate, cert); - nativeCerts.push_back(certificate); - info->certs.push_back(certificate->encode()); - } - - SSLCipherSuite cipher; - SSLGetNegotiatedCipher(_ssl, &cipher); - info->cipher = _engine->getCipherName(cipher); - info->verified = _verified; - } - else - { - info->verified = false; - } - - info->adapterName = _adapterName; - info->incoming = _incoming; -} - OSStatus IceSSL::TransceiverI::writeRaw(const char* data, size_t* length) const { @@ -592,13 +592,15 @@ IceSSL::TransceiverI::writeRaw(const char* data, size_t* length) const try { - ssize_t ret = _stream->write(data, *length); - if(ret < *length) + IceInternal::Buffer buf(reinterpret_cast<const Ice::Byte*>(data), reinterpret_cast<const Ice::Byte*>(data) + *length); + IceInternal::SocketOperation op = _delegate->write(buf); + if(op == IceInternal::SocketOperationWrite) { - *length = static_cast<size_t>(ret); + *length = buf.i - buf.b.begin(); _flags |= SSLWantWrite; return errSSLWouldBlock; } + assert(op == IceInternal::SocketOperationNone); } catch(const Ice::ConnectionLostException&) { @@ -623,13 +625,15 @@ IceSSL::TransceiverI::readRaw(char* data, size_t* length) const try { - ssize_t ret = _stream->read(data, *length); - if(ret < *length) + IceInternal::Buffer buf(reinterpret_cast<Ice::Byte*>(data), reinterpret_cast<Ice::Byte*>(data) + *length); + IceInternal::SocketOperation op = _delegate->read(buf); + if(op == IceInternal::SocketOperationRead) { - *length = static_cast<size_t>(ret); + *length = buf.i - buf.b.begin(); _flags |= SSLWantRead; return errSSLWouldBlock; } + assert(op == IceInternal::SocketOperationNone); } catch(const Ice::ConnectionLostException&) { diff --git a/cpp/src/IceSSL/SecureTransportTransceiverI.h b/cpp/src/IceSSL/SecureTransportTransceiverI.h index 68b0a677783..71a2a6c5f34 100644 --- a/cpp/src/IceSSL/SecureTransportTransceiverI.h +++ b/cpp/src/IceSSL/SecureTransportTransceiverI.h @@ -17,12 +17,11 @@ #include <Ice/Transceiver.h> #include <Ice/Network.h> -#include <Ice/StreamSocket.h> -#include <Ice/WSTransceiver.h> #ifdef ICE_USE_SECURE_TRANSPORT #include <Security/Security.h> +#include <Security/SecureTransport.h> #include <CoreFoundation/CoreFoundation.h> namespace IceSSL @@ -31,7 +30,7 @@ namespace IceSSL class ConnectorI; class AcceptorI; -class TransceiverI : public IceInternal::Transceiver, public IceInternal::WSTransceiverDelegate +class TransceiverI : public IceInternal::Transceiver { public: @@ -51,7 +50,6 @@ public: virtual std::string toString() const; virtual std::string toDetailedString() const; virtual Ice::ConnectionInfoPtr getInfo() const; - virtual Ice::ConnectionInfoPtr getWSInfo(const Ice::HeaderDict&) const; virtual void checkSendSize(const IceInternal::Buffer&); virtual void setBufferSize(int rcvSize, int sndSize); @@ -60,11 +58,9 @@ public: private: - TransceiverI(const InstancePtr&, const IceInternal::StreamSocketPtr&, const std::string&, bool); + TransceiverI(const InstancePtr&, const IceInternal::TransceiverPtr&, const std::string&, bool); virtual ~TransceiverI(); - void fillConnectionInfo(const ConnectionInfoPtr&, std::vector<CertificatePtr>&) const; - friend class ConnectorI; friend class AcceptorI; @@ -73,10 +69,11 @@ private: const std::string _host; const std::string _adapterName; const bool _incoming; - const IceInternal::StreamSocketPtr _stream; + const IceInternal::TransceiverPtr _delegate; SSLContextRef _ssl; SecTrustRef _trust; + bool _connected; bool _verified; size_t _buffered; diff --git a/cpp/src/IceSSL/TrustManager.cpp b/cpp/src/IceSSL/TrustManager.cpp index 0e60abb5a82..31b42291db3 100644 --- a/cpp/src/IceSSL/TrustManager.cpp +++ b/cpp/src/IceSSL/TrustManager.cpp @@ -62,7 +62,7 @@ TrustManager::TrustManager(const Ice::CommunicatorPtr& communicator) : } bool -TrustManager::verify(const NativeConnectionInfoPtr& info) +TrustManager::verify(const NativeConnectionInfoPtr& info, const std::string& desc) { list<list<DistinguishedName> > reject, accept; @@ -139,19 +139,14 @@ TrustManager::verify(const NativeConnectionInfoPtr& info) Ice::Trace trace(_communicator->getLogger(), "Security"); if(info->incoming) { - trace << "trust manager evaluating client:\n" - << "subject = " << string(subject) << '\n' - << "adapter = " << info->adapterName << '\n' - << "local addr = " << info->localAddress << ":" << info->localPort << '\n' - << "remote addr = " << info->remoteAddress << ":" << info->remotePort; + trace << "trust manager evaluating client:\n" << "subject = " << string(subject) << '\n' + << "adapter = " << info->adapterName << '\n'; } else { - trace << "trust manager evaluating server:\n" - << "subject = " << string(subject) << '\n' - << "local addr = " << info->localAddress << ":" << info->localPort << '\n' - << "remote addr = " << info->remoteAddress << ":" << info->remotePort; + trace << "trust manager evaluating server:\n" << "subject = " << string(subject) << '\n'; } + trace << desc; } // diff --git a/cpp/src/IceSSL/TrustManager.h b/cpp/src/IceSSL/TrustManager.h index a03c5d2a694..a99363baf05 100644 --- a/cpp/src/IceSSL/TrustManager.h +++ b/cpp/src/IceSSL/TrustManager.h @@ -25,7 +25,7 @@ public: TrustManager(const Ice::CommunicatorPtr&); - bool verify(const NativeConnectionInfoPtr&); + bool verify(const NativeConnectionInfoPtr&, const std::string&); private: diff --git a/cpp/src/IceSSL/Util.cpp b/cpp/src/IceSSL/Util.cpp index b55ca494233..9a5f6bce50e 100644..100755 --- a/cpp/src/IceSSL/Util.cpp +++ b/cpp/src/IceSSL/Util.cpp @@ -8,7 +8,7 @@ // ********************************************************************** #include <IceUtil/Config.h> -#ifdef _WIN32 +#if defined(_WIN32) && !defined(ICE_OS_WINRT) # include <winsock2.h> #endif @@ -16,6 +16,7 @@ #include <IceUtil/FileUtil.h> #include <IceUtil/StringUtil.h> +#include <Ice/Base64.h> #include <Ice/LocalException.h> #include <Ice/Network.h> #include <Ice/Object.h> @@ -33,30 +34,7 @@ using namespace Ice; using namespace IceUtil; using namespace IceSSL; -void -IceSSL::readFile(const string& file, vector<char>& buffer) -{ - IceUtilInternal::ifstream is(file, ios::in | ios::binary); - if(!is.good()) - { - throw CertificateReadException(__FILE__, __LINE__, "error opening file " + file); - } - - is.seekg(0, is.end); - buffer.resize(static_cast<int>(is.tellg())); - is.seekg(0, is.beg); - - if(!buffer.empty()) - { - is.read(&buffer[0], buffer.size()); - if(!is.good()) - { - throw CertificateReadException(__FILE__, __LINE__, "error reading file " + file); - } - } -} - -#ifndef ICE_USE_OPENSSL +#if !defined(ICE_USE_OPENSSL) namespace { @@ -423,12 +401,14 @@ IceSSL::errorToString(OSStatus status) { ostringstream os; os << "(error: " << status; +#if defined(ICE_USE_SECURE_TRANSPORT_MACOS) CFStringRef s = SecCopyErrorMessageString(status, 0); if(s) { os << " description: " << fromCFString(s); CFRelease(s); } +#endif os << ")"; return os.str(); } @@ -448,6 +428,7 @@ IceSSL::fromCFString(CFStringRef v) return s; } +#if defined(ICE_USE_SECURE_TRANSPORT_MACOS) CFDictionaryRef IceSSL::getCertificateProperty(SecCertificateRef cert, CFTypeRef key) { @@ -471,10 +452,36 @@ IceSSL::getCertificateProperty(SecCertificateRef cert, CFTypeRef key) CFRelease(values); return property; } +#endif namespace { +CFDataRef +readCertFile(const string& file) +{ + IceUtilInternal::ifstream is(file, ios::in | ios::binary); + if(!is.good()) + { + throw CertificateReadException(__FILE__, __LINE__, "error opening file " + file); + } + + is.seekg(0, is.end); + size_t size = is.tellg(); + is.seekg(0, is.beg); + + CFMutableDataRef data = CFDataCreateMutable(kCFAllocatorDefault, size); + CFDataSetLength(data, size); + is.read(reinterpret_cast<char*>(CFDataGetMutableBytePtr(data)), size); + if(!is.good()) + { + CFRelease(data); + throw CertificateReadException(__FILE__, __LINE__, "error reading file " + file); + } + return data; +} + +#if defined(ICE_USE_SECURE_TRANSPORT_MACOS) // // Check the certificate basic constraints to check if the certificate is marked as a CA. // @@ -506,12 +513,7 @@ CFArrayRef loadKeychainItems(const string& file, SecExternalItemType type, SecKeychainRef keychain, const string& passphrase, const PasswordPromptPtr& prompt, int retryMax) { - vector<char> buffer; - readFile(file, buffer); - UniqueRef<CFDataRef> data(CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, - reinterpret_cast<const UInt8*>(&buffer[0]), - buffer.size(), - kCFAllocatorNull)); + UniqueRef<CFDataRef> data(readCertFile(file)); SecItemImportExportKeyParameters params; memset(¶ms, 0, sizeof(params)); @@ -591,14 +593,93 @@ loadKeychainItems(const string& file, SecExternalItemType type, SecKeychainRef k return items; } +SecKeychainRef +openKeychain(const std::string& path, const std::string& keychainPassword) +{ + string keychainPath = path; + SecKeychainRef keychain = 0; + OSStatus err = 0; + if(keychainPath.empty()) + { + if((err = SecKeychainCopyDefault(&keychain))) + { + throw PluginInitializationException(__FILE__, __LINE__, + "IceSSL: unable to retrieve default keychain:\n" + errorToString(err)); + } + } + else + { + // + // KeyChain path is relative to the current working directory. + // + if(!IceUtilInternal::isAbsolutePath(keychainPath)) + { + string cwd; + if(IceUtilInternal::getcwd(cwd) == 0) + { + keychainPath = string(cwd) + '/' + keychainPath; + } + } + + if((err = SecKeychainOpen(keychainPath.c_str(), &keychain))) + { + throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: unable to open keychain: `" + + keychainPath + "'\n" + errorToString(err)); + } + } + + UniqueRef<SecKeychainRef> k(keychain); + + SecKeychainStatus status; + err = SecKeychainGetStatus(keychain, &status); + if(err == noErr) + { + const char* pass = keychainPassword.empty() ? 0 : keychainPassword.c_str(); + if((err = SecKeychainUnlock(keychain, keychainPassword.size(), pass, pass != 0))) + { + throw PluginInitializationException(__FILE__, __LINE__, + "IceSSL: unable to unlock keychain:\n" + errorToString(err)); + } + } + else if(err == errSecNoSuchKeychain) + { + const char* pass = keychainPassword.empty() ? 0 : keychainPassword.c_str(); + if((err = SecKeychainCreate(keychainPath.c_str(), keychainPassword.size(), pass, pass == 0, 0, &keychain))) + { + throw PluginInitializationException(__FILE__, __LINE__, + "IceSSL: unable to create keychain:\n" + errorToString(err)); + } + k.reset(keychain); + } + else + { + throw PluginInitializationException(__FILE__, __LINE__, + "IceSSL: unable to open keychain:\n" + errorToString(err)); + } + + // + // Set keychain settings to avoid keychain lock. + // + SecKeychainSettings settings; + settings.version = SEC_KEYCHAIN_SETTINGS_VERS1; + settings.lockOnSleep = FALSE; + settings.useLockInterval = FALSE; + settings.lockInterval = INT_MAX; + if((err = SecKeychainSetSettings(keychain, &settings))) + { + throw PluginInitializationException(__FILE__, __LINE__, + "IceSSL: error setting keychain settings:\n" + errorToString(err)); + } + + return k.release(); } // // Imports a certificate private key and optionally add it to a keychain. // SecIdentityRef -IceSSL::loadPrivateKey(const string& file, SecCertificateRef cert, SecKeychainRef keychain, const string& password, - const PasswordPromptPtr& prompt, int retryMax) +loadPrivateKey(const string& file, SecCertificateRef cert, SecKeychainRef keychain, const string& password, + const PasswordPromptPtr& prompt, int retryMax) { // // Check if we already imported the certificate @@ -751,17 +832,139 @@ IceSSL::loadPrivateKey(const string& file, SecCertificateRef cert, SecKeychainRe } return identity; } +#else + +CFArrayRef +loadCerts(const string& file) +{ + UniqueRef<CFMutableArrayRef> certs(CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks)); + if(file.find(".pem") != string::npos) + { + vector<char> buffer; + readFile(file, buffer); + string strbuf(buffer.begin(), buffer.end()); + string::size_type size, startpos, endpos = 0; + bool first = true; + while(true) + { + startpos = strbuf.find("-----BEGIN CERTIFICATE-----", endpos); + if(startpos != string::npos) + { + startpos += sizeof("-----BEGIN CERTIFICATE-----"); + endpos = strbuf.find("-----END CERTIFICATE-----", startpos); + if(endpos == string::npos) + { + InitializationException ex(__FILE__, __LINE__); + ex.reason = "IceSSL: certificate " + file + " is not a valid PEM-encoded certificate"; + throw ex; + } + size = endpos - startpos; + } + else if(first) + { + startpos = 0; + endpos = string::npos; + size = strbuf.size(); + } + else + { + break; + } + + vector<unsigned char> data(IceInternal::Base64::decode(string(&buffer[startpos], size))); + UniqueRef<CFDataRef> certdata(CFDataCreate(kCFAllocatorDefault, &data[0], data.size())); + SecCertificateRef cert = SecCertificateCreateWithData(0, certdata.get()); + if(!cert) + { + InitializationException ex(__FILE__, __LINE__); + ex.reason = "IceSSL: certificate " + file + " is not a valid PEM-encoded certificate"; + throw ex; + } + CFArrayAppendValue(certs.get(), cert); + CFRelease(cert); + first = false; + } + } + else + { + UniqueRef<CFDataRef> data(readCertFile(file)); + SecCertificateRef cert = SecCertificateCreateWithData(0, data.get()); + if(!cert) + { + InitializationException ex(__FILE__, __LINE__); + ex.reason = "IceSSL: certificate " + file + " is not a valid DER-encoded certificate"; + throw ex; + } + CFArrayAppendValue(certs.get(), cert); + CFRelease(cert); + } + return certs.release(); +} +#endif + +} // // Imports a certificate (it might contain an identity or certificate depending on the format). // CFArrayRef -IceSSL::loadCertificateChain(const string& file, const string& keyFile, SecKeychainRef keychain, - const string& password, const PasswordPromptPtr& prompt, int retryMax) +IceSSL::loadCertificateChain(const string& file, const string& keyFile, const std::string& keychainPath, + const string& keychainPassword, const string& password, const PasswordPromptPtr& prompt, + int retryMax) { +#if defined(ICE_USE_SECURE_TRANSPORT_IOS) + UniqueRef<CFDataRef> cert(readCertFile(file)); + + UniqueRef<CFMutableDictionaryRef> settings(CFDictionaryCreateMutable(0, 1, &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks)); + CFArrayRef items = 0; + OSStatus err; + if(password.empty() && prompt) + { + int count = 0; + do + { + UniqueRef<CFStringRef> pass(toCFString(prompt->getPassword())); + CFDictionarySetValue(settings.get(), kSecImportExportPassphrase, pass.get()); + err = SecPKCS12Import(cert.get(), settings.get(), &items); + ++count; + } + while(err == errSecAuthFailed && count < retryMax); + } + else + { + UniqueRef<CFStringRef> pass(toCFString(password)); + CFDictionarySetValue(settings.get(), kSecImportExportPassphrase, pass.get()); + err = SecPKCS12Import(cert.get(), settings.get(), &items); + } + if(err != noErr) + { + ostringstream os; + os << "IceSSL: unable to import certificate from file " << file << " (error = " << err << ")"; + throw InitializationException(__FILE__, __LINE__, os.str()); + } + + UniqueRef<CFArrayRef> itemsHolder(items);; + for(int i = 0; i < CFArrayGetCount(items); ++i) + { + CFDictionaryRef dict = (CFDictionaryRef)CFArrayGetValueAtIndex(items, i); + SecIdentityRef identity = (SecIdentityRef)CFDictionaryGetValue(dict, kSecImportItemIdentity); + if(identity) + { + CFArrayRef certs = (CFArrayRef)CFDictionaryGetValue(dict, kSecImportItemCertChain); + CFMutableArrayRef a = CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, certs); + CFArraySetValueAtIndex(a, 0, identity); + return a; + } + } + ostringstream os; + os << "IceSSL: couldn't find identity in file " << file; + throw InitializationException(__FILE__, __LINE__, os.str()); +#else + UniqueRef<SecKeychainRef> keychain(openKeychain(keychainPath, keychainPassword)); if(keyFile.empty()) { - return loadKeychainItems(file, kSecItemTypeUnknown, keychain, password, prompt, retryMax); + return loadKeychainItems(file, kSecItemTypeUnknown, keychain.get(), password, prompt, retryMax); } else { @@ -783,26 +986,37 @@ IceSSL::loadCertificateChain(const string& file, const string& keyFile, SecKeych // add the certificate/key to the keychain if they aren't // already present in the keychain. // - UniqueRef<SecIdentityRef> identity(loadPrivateKey(keyFile, cert, keychain, password, prompt, retryMax)); + UniqueRef<SecIdentityRef> identity(loadPrivateKey(keyFile, cert, keychain.get(), password, prompt, retryMax)); CFMutableArrayRef a = CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, items.get()); CFArraySetValueAtIndex(a, 0, identity.get()); return a; } +#endif } SecCertificateRef IceSSL::loadCertificate(const string& file) { - CFArrayRef items = loadKeychainItems(file, kSecItemTypeCertificate, 0, "", 0, 0); - SecCertificateRef cert = (SecCertificateRef)CFArrayGetValueAtIndex(items, 0); +#if defined(ICE_USE_SECURE_TRANSPORT_IOS) + UniqueRef<CFArrayRef> certs(loadCerts(file)); + assert(CFArrayGetCount(certs.get()) > 0); + SecCertificateRef cert = (SecCertificateRef)CFArrayGetValueAtIndex(certs.get(), 0); + CFRetain(cert); + return cert; +#else + UniqueRef<CFArrayRef> items(loadKeychainItems(file, kSecItemTypeCertificate, 0, "", 0, 0)); + SecCertificateRef cert = (SecCertificateRef)CFArrayGetValueAtIndex(items.get(), 0); CFRetain(cert); - CFRelease(items); return cert; +#endif } CFArrayRef IceSSL::loadCACertificates(const string& file) { +#if defined(ICE_USE_SECURE_TRANSPORT_IOS) + return loadCerts(file); +#else UniqueRef<CFArrayRef> items(loadKeychainItems(file, kSecItemTypeCertificate, 0, "", 0, 0)); CFMutableArrayRef certificateAuthorities = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); int count = CFArrayGetCount(items.get()); @@ -816,10 +1030,11 @@ IceSSL::loadCACertificates(const string& file) } } return certificateAuthorities; +#endif } -SecCertificateRef -IceSSL::findCertificate(SecKeychainRef keychain, const string& value) +CFArrayRef +IceSSL::findCertificateChain(const std::string& keychainPath, const std::string& keychainPassword, const string& value) { // // Search the keychain using key:value pairs. The following keys are supported: @@ -836,17 +1051,20 @@ IceSSL::findCertificate(SecKeychainRef keychain, const string& value) &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); - const void* values[] = { keychain }; +#if defined(ICE_USE_SECURE_TRANSPORT_MACOS) + UniqueRef<SecKeychainRef> keychain(openKeychain(keychainPath, keychainPassword)); + const void* values[] = { keychain.get() }; UniqueRef<CFArrayRef> searchList(CFArrayCreate(kCFAllocatorDefault, values, 1, &kCFTypeArrayCallBacks)); - - CFDictionarySetValue(query.get(), kSecMatchLimit, kSecMatchLimitOne); CFDictionarySetValue(query.get(), kSecMatchSearchList, searchList.get()); +#endif + CFDictionarySetValue(query.get(), kSecMatchLimit, kSecMatchLimitOne); CFDictionarySetValue(query.get(), kSecClass, kSecClassCertificate); CFDictionarySetValue(query.get(), kSecReturnRef, kCFBooleanTrue); CFDictionarySetValue(query.get(), kSecMatchCaseInsensitive, kCFBooleanTrue); size_t start = 0; size_t pos; + bool valid = false; while((pos = value.find(':', start)) != string::npos) { string field = IceUtilInternal::toUpper(IceUtilInternal::trim(value.substr(start, pos - start))); @@ -906,6 +1124,7 @@ IceSSL::findCertificate(SecKeychainRef keychain, const string& value) { UniqueRef<CFStringRef> v(toCFString(arg)); CFDictionarySetValue(query.get(), field == "LABEL" ? kSecAttrLabel : kSecMatchSubjectContains, v.get()); + valid = true; } else if(field == "SUBJECTKEYID" || field == "SERIAL") { @@ -917,10 +1136,11 @@ IceSSL::findCertificate(SecKeychainRef keychain, const string& value) UniqueRef<CFDataRef> v(CFDataCreate(kCFAllocatorDefault, &buffer[0], buffer.size())); CFDictionarySetValue(query.get(), field == "SUBJECTKEYID" ? kSecAttrSubjectKeyID : kSecAttrSerialNumber, v.get()); + valid = true; } } - if(CFDictionaryGetCount(query.get()) == 5) + if(!valid) { throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: invalid value `" + value + "'"); } @@ -932,7 +1152,92 @@ IceSSL::findCertificate(SecKeychainRef keychain, const string& value) throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: find certificate `" + value + "' failed:\n" + errorToString(err)); } - return cert; + + UniqueRef<SecCertificateRef> certHolder(cert); + + // + // Retrieve the certificate chain + // + UniqueRef<SecPolicyRef> policy(SecPolicyCreateSSL(true, 0)); + SecTrustRef trust = 0; + err = SecTrustCreateWithCertificates((CFArrayRef)cert, policy.get(), &trust); + if(err || !trust) + { + throw PluginInitializationException(__FILE__, __LINE__, + "IceSSL: error creating trust object" + + (err ? ":\n" + errorToString(err) : "")); + } + UniqueRef<SecTrustRef> v(trust); + + SecTrustResultType trustResult; + if((err = SecTrustEvaluate(trust, &trustResult))) + { + throw PluginInitializationException(__FILE__, __LINE__, + "IceSSL: error evaluating trust:\n" + errorToString(err)); + } + + int chainLength = SecTrustGetCertificateCount(trust); + CFMutableArrayRef items = CFArrayCreateMutable(kCFAllocatorDefault, chainLength, &kCFTypeArrayCallBacks); + UniqueRef<CFMutableArrayRef> itemsHolder(items); + for(int i = 0; i < chainLength; ++i) + { + CFArrayAppendValue(items, SecTrustGetCertificateAtIndex(trust, i)); + } + + // + // Replace the first certificate in the chain with the + // identity. + // + SecIdentityRef identity; +#if defined(ICE_USE_SECURE_TRANSPORT_IOS) + + // + // SecIdentityCreateWithCertificate isn't supported on iOS so we lookup the identity + // using the certicate label. If the user added the identity with SecItemAdd the + // identity has the same label as the certificate. + // + query.reset(CFDictionaryCreateMutable(0, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); + CFDictionarySetValue(query.get(), kSecClass, kSecClassCertificate); + CFDictionarySetValue(query.get(), kSecValueRef, cert); + CFDictionarySetValue(query.get(), kSecReturnAttributes, kCFBooleanTrue); + CFDictionaryRef attributes; + err = SecItemCopyMatching(query.get(), (CFTypeRef*)&attributes); + if(err != noErr) + { + ostringstream os; + os << "IceSSL: couldn't create identity for certificate found in the keychain:\n" << errorToString(err); + throw PluginInitializationException(__FILE__, __LINE__, os.str()); + } + UniqueRef<CFDictionaryRef> attributesHolder(attributes); + + // Now lookup the identity with the label + query.reset(CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); + CFDictionarySetValue(query.get(), kSecMatchLimit, kSecMatchLimitOne); + CFDictionarySetValue(query.get(), kSecClass, kSecClassIdentity); + CFDictionarySetValue(query.get(), kSecAttrLabel, (CFDataRef)CFDictionaryGetValue(attributes, kSecAttrLabel)); + CFDictionarySetValue(query.get(), kSecReturnRef, kCFBooleanTrue); + err = SecItemCopyMatching(query.get(), (CFTypeRef*)&identity); + if(err == noErr) + { + SecCertificateRef cert2 = NULL; + if((err = SecIdentityCopyCertificate(identity, &cert2)) == noErr) + { + err = CFEqual(cert2, cert) ? noErr : errSecItemNotFound; + CFRelease(cert2); + } + } +#else + err = SecIdentityCreateWithCertificate(keychain.get(), cert, &identity); +#endif + if(err != noErr) + { + ostringstream os; + os << "IceSSL: couldn't create identity for certificate found in the keychain:\n" << errorToString(err); + throw PluginInitializationException(__FILE__, __LINE__, os.str()); + } + CFArraySetValueAtIndex(items, 0, identity); + CFRelease(identity); + return itemsHolder.release(); } #elif defined(ICE_USE_SCHANNEL) @@ -1195,9 +1500,55 @@ IceSSL::findCertificates(const string& location, const string& name, const strin } #endif +void +IceSSL::readFile(const string& file, vector<char>& buffer) +{ + IceUtilInternal::ifstream is(file, ios::in | ios::binary); + if(!is.good()) + { + throw CertificateReadException(__FILE__, __LINE__, "error opening file " + file); + } + + is.seekg(0, is.end); + buffer.resize(static_cast<int>(is.tellg())); + is.seekg(0, is.beg); + + if(!buffer.empty()) + { + is.read(&buffer[0], buffer.size()); + if(!is.good()) + { + throw CertificateReadException(__FILE__, __LINE__, "error reading file " + file); + } + } +} + bool IceSSL::checkPath(const string& path, const string& defaultDir, bool dir, string& resolved) { +#if defined(ICE_USE_SECURE_TRANSPORT_IOS) + CFURLRef url = 0; + CFBundleRef bundle = CFBundleGetMainBundle(); + if(bundle) + { + CFStringRef resourceName = toCFString(path); + CFStringRef subDirName = toCFString(defaultDir); + url = CFBundleCopyResourceURL(bundle, resourceName, 0, subDirName); + CFRelease(resourceName); + CFRelease(subDirName); + + UInt8 filePath[PATH_MAX]; + if(CFURLGetFileSystemRepresentation(url, true, filePath, sizeof(filePath))) + { + string tmp = string(reinterpret_cast<char*>(filePath)); + if((dir && IceUtilInternal::directoryExists(tmp)) || (!dir && IceUtilInternal::fileExists(tmp))) + { + resolved = tmp; + return true; + } + } + } +#endif if(IceUtilInternal::isAbsolutePath(path)) { if((dir && IceUtilInternal::directoryExists(path)) || (!dir && IceUtilInternal::fileExists(path))) diff --git a/cpp/src/IceSSL/Util.h b/cpp/src/IceSSL/Util.h index 855e0ac71b8..3e98050ee35 100644 --- a/cpp/src/IceSSL/Util.h +++ b/cpp/src/IceSSL/Util.h @@ -150,27 +150,23 @@ toCFString(const std::string& s) std::string errorToString(CFErrorRef); std::string errorToString(OSStatus); +#if !defined(__APPLE__) || TARGET_OS_IPHONE == 0 // // Retrieve a certificate property // CFDictionaryRef getCertificateProperty(SecCertificateRef, CFTypeRef); - -// -// Read a private key from an file and associate it to the given certificate. -// -SecIdentityRef loadPrivateKey(const std::string&, SecCertificateRef, SecKeychainRef, const std::string&, - const PasswordPromptPtr&, int); +#endif // // Read certificate from a file. // -CFArrayRef loadCertificateChain(const std::string&, const std::string&, SecKeychainRef, const std::string&, - const PasswordPromptPtr&, int); +CFArrayRef loadCertificateChain(const std::string&, const std::string&, const std::string&, const std::string&, + const std::string&, const PasswordPromptPtr&, int); SecCertificateRef loadCertificate(const std::string&); CFArrayRef loadCACertificates(const std::string&); -SecCertificateRef findCertificate(SecKeychainRef, const std::string&); +CFArrayRef findCertificateChain(const std::string&, const std::string&, const std::string&); #elif defined(ICE_USE_SCHANNEL) std::vector<PCCERT_CONTEXT> diff --git a/cpp/src/IceSSL/WinRTEngine.cpp b/cpp/src/IceSSL/WinRTEngine.cpp new file mode 100755 index 00000000000..7eb59f922a7 --- /dev/null +++ b/cpp/src/IceSSL/WinRTEngine.cpp @@ -0,0 +1,43 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2016 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#include <IceSSL/Config.h> + +#ifdef ICE_OS_WINRT + +#include <IceSSL/SSLEngine.h> +#include <IceUtil/Shared.h> + +IceUtil::Shared* IceSSL::upCast(IceSSL::WinRTEngine* p) { return p; } + +using namespace IceSSL; + +WinRTEngine::WinRTEngine(const Ice::CommunicatorPtr& communicator) : SSLEngine(communicator) +{ + +} + +void +WinRTEngine::initialize() +{ +} + +bool +WinRTEngine::initialized() const +{ + return true; +} + +void +WinRTEngine::destroy() +{ +} + +#endif + diff --git a/cpp/src/IceSSL/WinRTTransceiverI.cpp b/cpp/src/IceSSL/WinRTTransceiverI.cpp new file mode 100755 index 00000000000..be0d632eaf8 --- /dev/null +++ b/cpp/src/IceSSL/WinRTTransceiverI.cpp @@ -0,0 +1,199 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2016 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#include <IceSSL/Config.h> + +#ifdef ICE_OS_WINRT + +#include <IceSSL/WinRTTransceiverI.h> +#include <IceSSL/Instance.h> +#include <IceSSL/SSLEngine.h> + +using namespace std; +using namespace Ice; +using namespace IceSSL; + +using namespace Platform; +using namespace Windows::Networking; +using namespace Windows::Networking::Sockets; + +IceInternal::NativeInfoPtr +IceSSL::TransceiverI::getNativeInfo() +{ + return _delegate->getNativeInfo(); +} + +IceInternal::SocketOperation +IceSSL::TransceiverI::initialize(IceInternal::Buffer& readBuffer, IceInternal::Buffer& writeBuffer) +{ + if(!_connected) + { + IceInternal::SocketOperation status = _delegate->initialize(readBuffer, writeBuffer); + if(status != IceInternal::SocketOperationNone) + { + return status; + } + _connected = true; + + // + // Continue connecting, this will call startWrite/finishWrite to upgrade the stream + // to SSL. + // + return IceInternal::SocketOperationConnect; + } + else if(!_upgraded) + { + _upgraded = true; + } + return IceInternal::SocketOperationNone; +} + +IceInternal::SocketOperation +#ifdef ICE_CPP11_MAPPING +IceSSL::TransceiverI::closing(bool initiator, exception_ptr ex) +#else +IceSSL::TransceiverI::closing(bool initiator, const Ice::LocalException& ex) +#endif +{ + return _delegate->closing(initiator, ex); +} + +void +IceSSL::TransceiverI::close() +{ + _delegate->close(); +} + +IceInternal::SocketOperation +IceSSL::TransceiverI::write(IceInternal::Buffer& buf) +{ + return _delegate->write(buf); +} + +IceInternal::SocketOperation +IceSSL::TransceiverI::read(IceInternal::Buffer& buf) +{ + return _delegate->read(buf); +} + +bool +IceSSL::TransceiverI::startWrite(IceInternal::Buffer& buf) +{ + if(_connected && !_upgraded) + { + StreamSocket^ stream = safe_cast<StreamSocket^>(_delegate->getNativeInfo()->fd()); + HostName^ host = ref new HostName(ref new String(IceUtil::stringToWstring(_host).c_str())); + try + { + Windows::Foundation::IAsyncAction^ action = stream->UpgradeToSslAsync(SocketProtectionLevel::Tls12, host); + getNativeInfo()->queueAction(IceInternal::SocketOperationWrite, action); + } + catch(Platform::Exception^ ex) + { + IceInternal::checkErrorCode(__FILE__, __LINE__, ex->HResult); + } + return true; + } + return _delegate->startWrite(buf); +} + +void +IceSSL::TransceiverI::finishWrite(IceInternal::Buffer& buf) +{ + if(_connected && !_upgraded) + { + IceInternal::AsyncInfo* asyncInfo = getNativeInfo()->getAsyncInfo(IceInternal::SocketOperationWrite); + if(asyncInfo->count == SOCKET_ERROR) + { + IceInternal::checkErrorCode(__FILE__, __LINE__, asyncInfo->error); + } + return; + } + _delegate->finishWrite(buf); +} + +void +IceSSL::TransceiverI::startRead(IceInternal::Buffer& buf) +{ + _delegate->startRead(buf); +} + +void +IceSSL::TransceiverI::finishRead(IceInternal::Buffer& buf) +{ + _delegate->finishRead(buf); +} + +string +IceSSL::TransceiverI::protocol() const +{ + return _instance->protocol(); +} + +string +IceSSL::TransceiverI::toString() const +{ + return _delegate->toString(); +} + +string +IceSSL::TransceiverI::toDetailedString() const +{ + return toString(); +} + +Ice::ConnectionInfoPtr +IceSSL::TransceiverI::getInfo() const +{ + NativeConnectionInfoPtr info = ICE_MAKE_SHARED(NativeConnectionInfo); + StreamSocket^ stream = safe_cast<StreamSocket^>(_delegate->getNativeInfo()->fd()); + info->nativeCerts.push_back(ICE_MAKE_SHARED(Certificate, stream->Information->ServerCertificate)); + info->certs.push_back(info->nativeCerts.back()->encode()); + for(auto iter = stream->Information->ServerIntermediateCertificates->First(); iter->HasCurrent; iter->MoveNext()) + { + info->nativeCerts.push_back(ICE_MAKE_SHARED(Certificate, iter->Current)); + info->certs.push_back(info->nativeCerts.back()->encode()); + } + info->adapterName = _adapterName; + info->incoming = _incoming; + info->underlying = _delegate->getInfo(); + return info; +} + +void +IceSSL::TransceiverI::checkSendSize(const IceInternal::Buffer&) +{ +} + +void +IceSSL::TransceiverI::setBufferSize(int rcvSize, int sndSize) +{ + _delegate->setBufferSize(rcvSize, sndSize); +} + +IceSSL::TransceiverI::TransceiverI(const InstancePtr& instance, + const IceInternal::TransceiverPtr& delegate, + const string& hostOrAdapterName, + bool incoming) : + _instance(instance), + _engine(WinRTEnginePtr::dynamicCast(instance->engine())), + _host(incoming ? "" : hostOrAdapterName), + _adapterName(incoming ? hostOrAdapterName : ""), + _incoming(incoming), + _delegate(delegate), + _connected(false), + _upgraded(false) +{ +} + +IceSSL::TransceiverI::~TransceiverI() +{ +} + +#endif diff --git a/cpp/src/IceSSL/WinRTTransceiverI.h b/cpp/src/IceSSL/WinRTTransceiverI.h new file mode 100755 index 00000000000..d3994eb359a --- /dev/null +++ b/cpp/src/IceSSL/WinRTTransceiverI.h @@ -0,0 +1,81 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2016 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef ICE_SSL_WINRT_TRANSCEIVER_I_H +#define ICE_SSL_WINRT_TRANSCEIVER_I_H + +#include <IceSSL/Config.h> + +#ifdef ICE_OS_WINRT + +#include <IceSSL/InstanceF.h> +#include <IceSSL/SSLEngineF.h> +#include <IceSSL/Plugin.h> + +#include <Ice/Transceiver.h> +#include <Ice/Network.h> + +namespace IceSSL +{ + +class ConnectorI; +class AcceptorI; + +class TransceiverI : public IceInternal::Transceiver +{ +public: + + virtual IceInternal::NativeInfoPtr getNativeInfo(); + + virtual IceInternal::SocketOperation initialize(IceInternal::Buffer&, IceInternal::Buffer&); +#ifdef ICE_CPP11_MAPPING + virtual IceInternal::SocketOperation closing(bool, std::exception_ptr); +#else + virtual IceInternal::SocketOperation closing(bool, const Ice::LocalException&); +#endif + virtual void close(); + virtual IceInternal::SocketOperation write(IceInternal::Buffer&); + virtual IceInternal::SocketOperation read(IceInternal::Buffer&); + virtual bool startWrite(IceInternal::Buffer&); + virtual void finishWrite(IceInternal::Buffer&); + virtual void startRead(IceInternal::Buffer&); + virtual void finishRead(IceInternal::Buffer&); + + virtual std::string protocol() const; + virtual std::string toString() const; + virtual std::string toDetailedString() const; + virtual Ice::ConnectionInfoPtr getInfo() const; + virtual void checkSendSize(const IceInternal::Buffer&); + virtual void setBufferSize(int rcvSize, int sndSize); + +private: + + TransceiverI(const InstancePtr&, const IceInternal::TransceiverPtr&, const std::string&, bool); + virtual ~TransceiverI(); + + friend class ConnectorI; + friend class AcceptorI; + + const InstancePtr _instance; + const WinRTEnginePtr _engine; + const std::string _host; + const std::string _adapterName; + const bool _incoming; + const IceInternal::TransceiverPtr _delegate; + + bool _connected; + bool _upgraded; +}; +typedef IceUtil::Handle<TransceiverI> TransceiverIPtr; + +} + +#endif + +#endif diff --git a/cpp/src/IceSSL/msbuild/icessluwp++11/icessluwp++11.vcxproj b/cpp/src/IceSSL/msbuild/icessluwp++11/icessluwp++11.vcxproj index 2b35204da8a..6b376e66034 100644 --- a/cpp/src/IceSSL/msbuild/icessluwp++11/icessluwp++11.vcxproj +++ b/cpp/src/IceSSL/msbuild/icessluwp++11/icessluwp++11.vcxproj @@ -136,10 +136,18 @@ <IceBuilder Include="..\..\..\..\..\slice\IceSSL\EndpointInfo.ice" /> </ItemGroup> <ItemGroup> - <ClCompile Include="..\..\uwp\AcceptorI.cpp" /> - <ClCompile Include="..\..\uwp\ConnectorI.cpp" /> - <ClCompile Include="..\..\uwp\EndpointI.cpp" /> - <ClCompile Include="..\..\uwp\TransceiverI.cpp" /> + <ClCompile Include="..\..\AcceptorI.cpp" /> + <ClCompile Include="..\..\Certificate.cpp" /> + <ClCompile Include="..\..\ConnectorI.cpp" /> + <ClCompile Include="..\..\EndpointI.cpp" /> + <ClCompile Include="..\..\Instance.cpp" /> + <ClCompile Include="..\..\PluginI.cpp" /> + <ClCompile Include="..\..\RFC2253.cpp" /> + <ClCompile Include="..\..\SSLEngine.cpp" /> + <ClCompile Include="..\..\TrustManager.cpp" /> + <ClCompile Include="..\..\Util.cpp" /> + <ClCompile Include="..\..\WinRTEngine.cpp" /> + <ClCompile Include="..\..\WinRTTransceiverI.cpp" /> <ClCompile Include="ARM\Debug\ConnectionInfo.cpp"> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> diff --git a/cpp/src/IceSSL/msbuild/icessluwp++11/icessluwp++11.vcxproj.filters b/cpp/src/IceSSL/msbuild/icessluwp++11/icessluwp++11.vcxproj.filters index 7d141e0bffd..17f262f778e 100644 --- a/cpp/src/IceSSL/msbuild/icessluwp++11/icessluwp++11.vcxproj.filters +++ b/cpp/src/IceSSL/msbuild/icessluwp++11/icessluwp++11.vcxproj.filters @@ -75,18 +75,6 @@ </IceBuilder> </ItemGroup> <ItemGroup> - <ClCompile Include="..\..\uwp\AcceptorI.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\uwp\ConnectorI.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\uwp\EndpointI.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\uwp\TransceiverI.cpp"> - <Filter>Source Files</Filter> - </ClCompile> <ClCompile Include="Win32\Debug\ConnectionInfo.cpp"> <Filter>Source Files\Win32\Debug</Filter> </ClCompile> @@ -123,6 +111,40 @@ <ClCompile Include="x64\Release\EndpointInfo.cpp"> <Filter>Source Files\x64\Release</Filter> </ClCompile> + <ClCompile Include="..\..\ConnectorI.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\AcceptorI.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\EndpointI.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\Instance.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\SSLEngine.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\TrustManager.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\WinRTTransceiverI.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\PluginI.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\Certificate.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\Util.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\WinRTEngine.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\RFC2253.cpp" /> </ItemGroup> <ItemGroup> <ClInclude Include="..\..\uwp\AcceptorI.h"> diff --git a/cpp/src/slice2cpp/Gen.cpp b/cpp/src/slice2cpp/Gen.cpp index 81c335ad2dc..5fe808581fa 100644 --- a/cpp/src/slice2cpp/Gen.cpp +++ b/cpp/src/slice2cpp/Gen.cpp @@ -2527,7 +2527,7 @@ Slice::Gen::ObjectVisitor::visitClassDefStart(const ClassDefPtr& p) } bool hasBaseClass = !bases.empty() && !bases.front()->isInterface(); - bool override = p->canBeCyclic() && (!hasBaseClass || !bases.front()->canBeCyclic()); + bool override = !p->isLocal() && p->canBeCyclic() && (!hasBaseClass || !bases.front()->canBeCyclic()); bool hasGCObjectBaseClass = basePreserved || override || preserved; if(!basePreserved && (override || preserved)) { diff --git a/cpp/test/Ice/background/EndpointFactory.cpp b/cpp/test/Ice/background/EndpointFactory.cpp index 9cf7d4a16eb..bf1cb1422b0 100644 --- a/cpp/test/Ice/background/EndpointFactory.cpp +++ b/cpp/test/Ice/background/EndpointFactory.cpp @@ -56,7 +56,7 @@ EndpointFactory::destroy() } IceInternal::EndpointFactoryPtr -EndpointFactory::clone(const IceInternal::ProtocolInstancePtr&) const +EndpointFactory::clone(const IceInternal::ProtocolInstancePtr&, const IceInternal::EndpointFactoryPtr&) const { return const_cast<EndpointFactory*>(this); } diff --git a/cpp/test/Ice/background/EndpointFactory.h b/cpp/test/Ice/background/EndpointFactory.h index 5f265996bd8..9dab2bac2ef 100644 --- a/cpp/test/Ice/background/EndpointFactory.h +++ b/cpp/test/Ice/background/EndpointFactory.h @@ -24,7 +24,8 @@ public: virtual IceInternal::EndpointIPtr read(Ice::InputStream*) const; virtual void destroy(); - virtual IceInternal::EndpointFactoryPtr clone(const IceInternal::ProtocolInstancePtr&) const; + virtual IceInternal::EndpointFactoryPtr clone(const IceInternal::ProtocolInstancePtr&, + const IceInternal::EndpointFactoryPtr&) const; protected: diff --git a/cpp/test/Ice/background/EndpointI.cpp b/cpp/test/Ice/background/EndpointI.cpp index 6cd3550e563..76748bea94a 100644 --- a/cpp/test/Ice/background/EndpointI.cpp +++ b/cpp/test/Ice/background/EndpointI.cpp @@ -32,12 +32,10 @@ EndpointI::EndpointI(const IceInternal::EndpointIPtr& endpoint) : } void -EndpointI::streamWrite(Ice::OutputStream* s) const +EndpointI::streamWriteImpl(Ice::OutputStream* s) const { - s->startEncapsulation(); s->write(_endpoint->type()); _endpoint->streamWrite(s); - s->endEncapsulation(); } Ice::Short diff --git a/cpp/test/Ice/background/EndpointI.h b/cpp/test/Ice/background/EndpointI.h index ea9423331b6..2e8b823b7a4 100644 --- a/cpp/test/Ice/background/EndpointI.h +++ b/cpp/test/Ice/background/EndpointI.h @@ -23,11 +23,11 @@ class EndpointI : public IceInternal::EndpointI, public Ice::EnableSharedFromThi public: static Ice::Short TYPE_BASE; - + EndpointI(const IceInternal::EndpointIPtr&); // From EndpointI - virtual void streamWrite(Ice::OutputStream*) const; + virtual void streamWriteImpl(Ice::OutputStream*) const; virtual Ice::Short type() const; virtual const std::string& protocol() const; virtual IceInternal::EndpointIPtr timeout(Ice::Int) const; diff --git a/cpp/test/Ice/info/AllTests.cpp b/cpp/test/Ice/info/AllTests.cpp index 81da1e2aafa..e9edf0327ee 100644 --- a/cpp/test/Ice/info/AllTests.cpp +++ b/cpp/test/Ice/info/AllTests.cpp @@ -15,6 +15,39 @@ using namespace std; using namespace Test; +namespace +{ + +Ice::TCPEndpointInfoPtr +getTCPEndpointInfo(const Ice::EndpointInfoPtr& info) +{ + for(Ice::EndpointInfoPtr p = info; p; p = p->underlying) + { + Ice::TCPEndpointInfoPtr tcpInfo = ICE_DYNAMIC_CAST(Ice::TCPEndpointInfo, p); + if(tcpInfo) + { + return tcpInfo; + } + } + return ICE_NULLPTR; +} + +Ice::TCPConnectionInfoPtr +getTCPConnectionInfo(const Ice::ConnectionInfoPtr& info) +{ + for(Ice::ConnectionInfoPtr p = info; p; p = p->underlying) + { + Ice::TCPConnectionInfoPtr tcpInfo = ICE_DYNAMIC_CAST(Ice::TCPConnectionInfo, p); + if(tcpInfo) + { + return tcpInfo; + } + } + return ICE_NULLPTR; +} + +} + void allTests(const Ice::CommunicatorPtr& communicator) { @@ -27,7 +60,8 @@ allTests(const Ice::CommunicatorPtr& communicator) Ice::EndpointSeq endps = p1->ice_getEndpoints(); - Ice::IPEndpointInfoPtr ipEndpoint = ICE_DYNAMIC_CAST(Ice::IPEndpointInfo, endps[0]->getInfo()); + Ice::EndpointInfoPtr info = endps[0]->getInfo(); + Ice::TCPEndpointInfoPtr ipEndpoint = getTCPEndpointInfo(info); test(ipEndpoint); test(ipEndpoint->host == "tcphost"); test(ipEndpoint->port == 10000); @@ -38,13 +72,14 @@ allTests(const Ice::CommunicatorPtr& communicator) test(ipEndpoint->compress); test(!ipEndpoint->datagram()); test((ipEndpoint->type() == Ice::TCPEndpointType && !ipEndpoint->secure()) || - (ipEndpoint->type() == IceSSL::EndpointType && ipEndpoint->secure()) || + (ipEndpoint->type() == Ice::SSLEndpointType && ipEndpoint->secure()) || (ipEndpoint->type() == Ice::WSEndpointType && !ipEndpoint->secure()) || (ipEndpoint->type() == Ice::WSSEndpointType && ipEndpoint->secure())); - test((ipEndpoint->type() == Ice::TCPEndpointType && ICE_DYNAMIC_CAST(Ice::TCPEndpointInfo, ipEndpoint)) || - (ipEndpoint->type() == IceSSL::EndpointType && ICE_DYNAMIC_CAST(IceSSL::EndpointInfo, ipEndpoint)) || - (ipEndpoint->type() == Ice::WSEndpointType && ICE_DYNAMIC_CAST(Ice::WSEndpointInfo, ipEndpoint)) || - (ipEndpoint->type() == Ice::WSSEndpointType && ICE_DYNAMIC_CAST(IceSSL::WSSEndpointInfo, ipEndpoint))); + + test((ipEndpoint->type() == Ice::TCPEndpointType && ICE_DYNAMIC_CAST(Ice::TCPEndpointInfo, info)) || + (ipEndpoint->type() == Ice::SSLEndpointType && ICE_DYNAMIC_CAST(IceSSL::EndpointInfo, info)) || + (ipEndpoint->type() == Ice::WSEndpointType && ICE_DYNAMIC_CAST(Ice::WSEndpointInfo, info)) || + (ipEndpoint->type() == Ice::WSSEndpointType && ICE_DYNAMIC_CAST(Ice::WSEndpointInfo, info))); Ice::UDPEndpointInfoPtr udpEndpoint = ICE_DYNAMIC_CAST(Ice::UDPEndpointInfo, endps[1]->getInfo()); test(udpEndpoint); @@ -81,9 +116,9 @@ allTests(const Ice::CommunicatorPtr& communicator) Ice::EndpointSeq publishedEndpoints = adapter->getPublishedEndpoints(); test(endpoints == publishedEndpoints); - Ice::IPEndpointInfoPtr ipEndpoint = ICE_DYNAMIC_CAST(Ice::IPEndpointInfo, endpoints[0]->getInfo()); + Ice::TCPEndpointInfoPtr ipEndpoint = getTCPEndpointInfo(endpoints[0]->getInfo()); test(ipEndpoint); - test(ipEndpoint->type() == Ice::TCPEndpointType || ipEndpoint->type() == IceSSL::EndpointType || + test(ipEndpoint->type() == Ice::TCPEndpointType || ipEndpoint->type() == Ice::SSLEndpointType || ipEndpoint->type() == Ice::WSEndpointType || ipEndpoint->type() == Ice::WSSEndpointType); test(ipEndpoint->host == "127.0.0.1"); test(ipEndpoint->port > 0); @@ -108,11 +143,11 @@ allTests(const Ice::CommunicatorPtr& communicator) for(Ice::EndpointSeq::const_iterator p = endpoints.begin(); p != endpoints.end(); ++p) { - ipEndpoint = ICE_DYNAMIC_CAST(Ice::IPEndpointInfo, (*p)->getInfo()); + ipEndpoint = getTCPEndpointInfo((*p)->getInfo()); test(ipEndpoint->port == 12020); } - ipEndpoint = ICE_DYNAMIC_CAST(Ice::IPEndpointInfo, publishedEndpoints[0]->getInfo()); + ipEndpoint = getTCPEndpointInfo(publishedEndpoints[0]->getInfo()); test(ipEndpoint->host == "127.0.0.1"); test(ipEndpoint->port == 12020); @@ -126,15 +161,15 @@ allTests(const Ice::CommunicatorPtr& communicator) cout << "test connection endpoint information... " << flush; { Ice::EndpointInfoPtr info = base->ice_getConnection()->getEndpoint()->getInfo(); - Ice::IPEndpointInfoPtr ipinfo = ICE_DYNAMIC_CAST(Ice::IPEndpointInfo, info); - test(ipinfo->port == 12010); - test(!ipinfo->compress); - test(ipinfo->host == defaultHost); + Ice::TCPEndpointInfoPtr tcpinfo = getTCPEndpointInfo(info); + test(tcpinfo->port == 12010); + test(!tcpinfo->compress); + test(tcpinfo->host == defaultHost); ostringstream os; Ice::Context ctx = testIntf->getEndpointInfoAsContext(); - test(ctx["host"] == ipinfo->host); + test(ctx["host"] == tcpinfo->host); test(ctx["compress"] == "false"); istringstream is(ctx["port"]); int port; @@ -154,7 +189,7 @@ allTests(const Ice::CommunicatorPtr& communicator) Ice::ConnectionPtr connection = base->ice_getConnection(); connection->setBufferSize(1024, 2048); - Ice::IPConnectionInfoPtr info = ICE_DYNAMIC_CAST(Ice::IPConnectionInfo, connection->getInfo()); + Ice::TCPConnectionInfoPtr info = getTCPConnectionInfo(connection->getInfo()); test(info); test(!info->incoming); test(info->adapterName.empty()); @@ -188,16 +223,13 @@ allTests(const Ice::CommunicatorPtr& communicator) { Ice::HeaderDict headers; - Ice::WSConnectionInfoPtr wsinfo = ICE_DYNAMIC_CAST(Ice::WSConnectionInfo, info); - if(wsinfo) - { - headers = wsinfo->headers; - } + Ice::WSConnectionInfoPtr wsinfo = ICE_DYNAMIC_CAST(Ice::WSConnectionInfo, connection->getInfo()); + test(wsinfo); + headers = wsinfo->headers; - IceSSL::WSSConnectionInfoPtr wssinfo = ICE_DYNAMIC_CAST(IceSSL::WSSConnectionInfo, info); - if(wssinfo) + if(base->ice_getConnection()->type() == "wss") { - headers = wssinfo->headers; + IceSSL::ConnectionInfoPtr wssinfo = ICE_DYNAMIC_CAST(IceSSL::ConnectionInfo, wsinfo->underlying); test(wssinfo->verified); #if !defined(ICE_OS_WINRT) && TARGET_OS_IPHONE==0 test(!wssinfo->certs.empty()); @@ -219,20 +251,20 @@ allTests(const Ice::CommunicatorPtr& communicator) connection = base->ice_datagram()->ice_getConnection(); connection->setBufferSize(2048, 1024); - info = ICE_DYNAMIC_CAST(Ice::IPConnectionInfo, connection->getInfo()); - test(!info->incoming); - test(info->adapterName.empty()); - test(info->localPort > 0); - test(info->remotePort == 12010); + Ice::UDPConnectionInfoPtr udpinfo = ICE_DYNAMIC_CAST(Ice::UDPConnectionInfo, connection->getInfo()); + test(!udpinfo->incoming); + test(udpinfo->adapterName.empty()); + test(udpinfo->localPort > 0); + test(udpinfo->remotePort == 12010); if(defaultHost == "127.0.0.1") { - test(info->remoteAddress == defaultHost); - test(info->localAddress == defaultHost); + test(udpinfo->remoteAddress == defaultHost); + test(udpinfo->localAddress == defaultHost); } #if !defined(ICE_OS_WINRT) - test(info->rcvSize >= 2048); - test(info->sndSize >= 1024); + test(udpinfo->rcvSize >= 2048); + test(udpinfo->sndSize >= 1024); #endif } cout << "ok" << endl; diff --git a/cpp/test/Ice/info/TestI.cpp b/cpp/test/Ice/info/TestI.cpp index ddacb9874dc..06e17ab89a1 100644 --- a/cpp/test/Ice/info/TestI.cpp +++ b/cpp/test/Ice/info/TestI.cpp @@ -16,6 +16,39 @@ using namespace std; using namespace Ice; using namespace Test; +namespace +{ + +Ice::IPEndpointInfoPtr +getIPEndpointInfo(const Ice::EndpointInfoPtr& info) +{ + for(Ice::EndpointInfoPtr p = info; p; p = p->underlying) + { + Ice::IPEndpointInfoPtr ipInfo = ICE_DYNAMIC_CAST(Ice::IPEndpointInfo, p); + if(ipInfo) + { + return ipInfo; + } + } + return ICE_NULLPTR; +} + +Ice::IPConnectionInfoPtr +getIPConnectionInfo(const Ice::ConnectionInfoPtr& info) +{ + for(Ice::ConnectionInfoPtr p = info; p; p = p->underlying) + { + Ice::IPConnectionInfoPtr ipInfo = ICE_DYNAMIC_CAST(Ice::IPConnectionInfo, p); + if(ipInfo) + { + return ipInfo; + } + } + return ICE_NULLPTR; +} + +} + void TestI::shutdown(const Ice::Current& current) { @@ -38,8 +71,8 @@ TestI::getEndpointInfoAsContext(const Ice::Current& c) os << info->type(); ctx["type"] = os.str(); - Ice::IPEndpointInfoPtr ipinfo = ICE_DYNAMIC_CAST(Ice::IPEndpointInfo, info); - test(info); + Ice::IPEndpointInfoPtr ipinfo = getIPEndpointInfo(info); + test(ipinfo); ctx["host"] = ipinfo->host; os.str(""); os << ipinfo->port; @@ -64,7 +97,7 @@ TestI::getConnectionInfoAsContext(const Ice::Current& c) ctx["incoming"] = info->incoming ? "true" : "false"; ostringstream os; - Ice::IPConnectionInfoPtr ipinfo = ICE_DYNAMIC_CAST(Ice::IPConnectionInfo, info); + Ice::IPConnectionInfoPtr ipinfo = getIPConnectionInfo(info); test(ipinfo); ctx["localAddress"] = ipinfo->localAddress; os.str(""); @@ -84,14 +117,5 @@ TestI::getConnectionInfoAsContext(const Ice::Current& c) } } - IceSSL::WSSConnectionInfoPtr wssinfo = ICE_DYNAMIC_CAST(IceSSL::WSSConnectionInfo, info); - if(wssinfo) - { - for(Ice::HeaderDict::const_iterator p = wssinfo->headers.begin(); p != wssinfo->headers.end(); ++p) - { - ctx["ws." + p->first] = p->second; - } - } - return ctx; } diff --git a/cpp/test/Ice/metrics/AllTests.cpp b/cpp/test/Ice/metrics/AllTests.cpp index 08e6ba8e8af..86fba324ef5 100644 --- a/cpp/test/Ice/metrics/AllTests.cpp +++ b/cpp/test/Ice/metrics/AllTests.cpp @@ -494,6 +494,24 @@ allTests(const Ice::CommunicatorPtr& communicator, const CommunicatorObserverIPt map<string, IceMX::MetricsPtr> map; + string endpoint; + { + ostringstream os; + os << communicator->getProperties()->getPropertyWithDefault("Ice.Default.Protocol", "tcp") << " -h 127.0.0.1 -p 12010"; + endpoint = os.str(); + } + string type; + string isSecure; + if(!collocated) + { + Ice::EndpointInfoPtr endpointInfo = metrics->ice_getConnection()->getEndpoint()->getInfo(); + { + ostringstream os; + os << endpointInfo->type(); + type = os.str(); + } + isSecure = endpointInfo->secure() ? "true": "false"; + } if(!collocated) { cout << "testing connection metrics... " << flush; @@ -567,7 +585,8 @@ allTests(const Ice::CommunicatorPtr& communicator, const CommunicatorObserverIPt updateProps(clientProps, serverProps, update.get(), props, "Connection"); map = toMap(serverMetrics->getMetricsView("View", timestamp)["Connection"]); - + test(map["active"]->current == 1); + map = toMap(clientMetrics->getMetricsView("View", timestamp)["Connection"]); test(map["active"]->current == 1); ControllerPrxPtr controller = ICE_CHECKED_CAST(ControllerPrx, communicator->stringToProxy("controller:default -p 12011")); @@ -631,11 +650,10 @@ allTests(const Ice::CommunicatorPtr& communicator, const CommunicatorObserverIPt testAttribute(clientMetrics, clientProps, update.get(), "Connection", "parent", "Communicator"); //testAttribute(clientMetrics, clientProps, update.get(), "Connection", "id", ""); - testAttribute(clientMetrics, clientProps, update.get(), "Connection", "endpoint", "tcp -h 127.0.0.1 -p 12010 -t 500"); - - testAttribute(clientMetrics, clientProps, update.get(), "Connection", "endpointType", "1"); + testAttribute(clientMetrics, clientProps, update.get(), "Connection", "endpoint", endpoint + " -t 500"); + testAttribute(clientMetrics, clientProps, update.get(), "Connection", "endpointType", type); testAttribute(clientMetrics, clientProps, update.get(), "Connection", "endpointIsDatagram", "false"); - testAttribute(clientMetrics, clientProps, update.get(), "Connection", "endpointIsSecure", "false"); + testAttribute(clientMetrics, clientProps, update.get(), "Connection", "endpointIsSecure", isSecure); testAttribute(clientMetrics, clientProps, update.get(), "Connection", "endpointTimeout", "500"); testAttribute(clientMetrics, clientProps, update.get(), "Connection", "endpointCompress", "false"); testAttribute(clientMetrics, clientProps, update.get(), "Connection", "endpointHost", "127.0.0.1"); @@ -695,11 +713,11 @@ allTests(const Ice::CommunicatorPtr& communicator, const CommunicatorObserverIPt testAttribute(clientMetrics, clientProps, update.get(), "ConnectionEstablishment", "parent", "Communicator", c); testAttribute(clientMetrics, clientProps, update.get(), "ConnectionEstablishment", "id", "127.0.0.1:12010", c); testAttribute(clientMetrics, clientProps, update.get(), "ConnectionEstablishment", "endpoint", - "tcp -h 127.0.0.1 -p 12010 -t 60000", c); + endpoint + " -t 60000", c); - testAttribute(clientMetrics, clientProps, update.get(), "ConnectionEstablishment", "endpointType", "1", c); + testAttribute(clientMetrics, clientProps, update.get(), "ConnectionEstablishment", "endpointType", type, c); testAttribute(clientMetrics, clientProps, update.get(), "ConnectionEstablishment", "endpointIsDatagram", "false", c); - testAttribute(clientMetrics, clientProps, update.get(), "ConnectionEstablishment", "endpointIsSecure", "false", c); + testAttribute(clientMetrics, clientProps, update.get(), "ConnectionEstablishment", "endpointIsSecure", isSecure, c); testAttribute(clientMetrics, clientProps, update.get(), "ConnectionEstablishment", "endpointTimeout", "60000", c); testAttribute(clientMetrics, clientProps, update.get(), "ConnectionEstablishment", "endpointCompress", "false", c); testAttribute(clientMetrics, clientProps, update.get(), "ConnectionEstablishment", "endpointHost", "127.0.0.1", c); @@ -724,7 +742,7 @@ allTests(const Ice::CommunicatorPtr& communicator, const CommunicatorObserverIPt test(clientMetrics->getMetricsView("View", timestamp)["EndpointLookup"].size() == 1); m1 = clientMetrics->getMetricsView("View", timestamp)["EndpointLookup"][0]; - test(m1->current <= 1 && m1->total == 1 && m1->id == "tcp -h localhost -p 12010 -t infinite"); + test(m1->current <= 1 && m1->total == 1 && m1->id == prx->ice_getConnection()->getEndpoint()->toString()); prx->ice_getConnection()->close(false); @@ -755,13 +773,13 @@ allTests(const Ice::CommunicatorPtr& communicator, const CommunicatorObserverIPt testAttribute(clientMetrics, clientProps, update.get(), "EndpointLookup", "parent", "Communicator", c); testAttribute(clientMetrics, clientProps, update.get(), "EndpointLookup", "id", - "tcp -h localhost -p 12010 -t infinite", c); + prx->ice_getConnection()->getEndpoint()->toString(), c); testAttribute(clientMetrics, clientProps, update.get(), "EndpointLookup", "endpoint", - "tcp -h localhost -p 12010 -t infinite", c); + prx->ice_getConnection()->getEndpoint()->toString(), c); - testAttribute(clientMetrics, clientProps, update.get(), "EndpointLookup", "endpointType", "1", c); + testAttribute(clientMetrics, clientProps, update.get(), "EndpointLookup", "endpointType", type, c); testAttribute(clientMetrics, clientProps, update.get(), "EndpointLookup", "endpointIsDatagram", "false", c); - testAttribute(clientMetrics, clientProps, update.get(), "EndpointLookup", "endpointIsSecure", "false", c); + testAttribute(clientMetrics, clientProps, update.get(), "EndpointLookup", "endpointIsSecure", isSecure, c); testAttribute(clientMetrics, clientProps, update.get(), "EndpointLookup", "endpointTimeout", "-1", c); testAttribute(clientMetrics, clientProps, update.get(), "EndpointLookup", "endpointCompress", "false", c); testAttribute(clientMetrics, clientProps, update.get(), "EndpointLookup", "endpointHost", "localhost", c); @@ -861,13 +879,12 @@ allTests(const Ice::CommunicatorPtr& communicator, const CommunicatorObserverIPt testAttribute(serverMetrics, serverProps, update.get(), "Dispatch", "id", "metrics [op]", op); if(!collocated) { - testAttribute(serverMetrics, serverProps, update.get(), "Dispatch", "endpoint", "tcp -h 127.0.0.1 -p 12010 -t 60000", - op); + testAttribute(serverMetrics, serverProps, update.get(), "Dispatch", "endpoint", endpoint + " -t 60000", op); //testAttribute(serverMetrics, serverProps, update.get(), "Dispatch", "connection", "", op); - testAttribute(serverMetrics, serverProps, update.get(), "Dispatch", "endpointType", "1", op); + testAttribute(serverMetrics, serverProps, update.get(), "Dispatch", "endpointType", type, op); testAttribute(serverMetrics, serverProps, update.get(), "Dispatch", "endpointIsDatagram", "false", op); - testAttribute(serverMetrics, serverProps, update.get(), "Dispatch", "endpointIsSecure", "false", op); + testAttribute(serverMetrics, serverProps, update.get(), "Dispatch", "endpointIsSecure", isSecure, op); testAttribute(serverMetrics, serverProps, update.get(), "Dispatch", "endpointTimeout", "60000", op); testAttribute(serverMetrics, serverProps, update.get(), "Dispatch", "endpointCompress", "false", op); testAttribute(serverMetrics, serverProps, update.get(), "Dispatch", "endpointHost", "127.0.0.1", op); @@ -1275,8 +1292,7 @@ allTests(const Ice::CommunicatorPtr& communicator, const CommunicatorObserverIPt testAttribute(clientMetrics, clientProps, update.get(), "Invocation", "encoding", "1.1", op); testAttribute(clientMetrics, clientProps, update.get(), "Invocation", "mode", "twoway", op); testAttribute(clientMetrics, clientProps, update.get(), "Invocation", "proxy", - "metrics -t -e 1.1:tcp -h 127.0.0.1 -p 12010 -t 60000", op); - + "metrics -t -e 1.1:" + endpoint + " -t 60000", op); testAttribute(clientMetrics, clientProps, update.get(), "Invocation", "context.entry1", "test", op); testAttribute(clientMetrics, clientProps, update.get(), "Invocation", "context.entry2", "", op); testAttribute(clientMetrics, clientProps, update.get(), "Invocation", "context.entry3", "", op); diff --git a/cpp/test/Ice/metrics/Client.cpp b/cpp/test/Ice/metrics/Client.cpp index 88c19ae6f18..65611a7de95 100644 --- a/cpp/test/Ice/metrics/Client.cpp +++ b/cpp/test/Ice/metrics/Client.cpp @@ -36,7 +36,7 @@ main(int argc, char* argv[]) { Ice::InitializationData initData; initData.properties = Ice::createProperties(argc, argv); - initData.properties->setProperty("Ice.Admin.Endpoints", "tcp"); + initData.properties->setProperty("Ice.Admin.Endpoints", "default"); initData.properties->setProperty("Ice.Admin.InstanceName", "client"); initData.properties->setProperty("Ice.Admin.DelayCreation", "1"); initData.properties->setProperty("Ice.Warn.Connections", "0"); diff --git a/cpp/test/Ice/networkProxy/AllTests.cpp b/cpp/test/Ice/networkProxy/AllTests.cpp index 3ab6aedcffd..f1d2fa1fe71 100644 --- a/cpp/test/Ice/networkProxy/AllTests.cpp +++ b/cpp/test/Ice/networkProxy/AllTests.cpp @@ -14,6 +14,25 @@ using namespace std; using namespace Test; +namespace +{ + +Ice::IPConnectionInfoPtr +getIPConnectionInfo(const Ice::ConnectionInfoPtr& info) +{ + for(Ice::ConnectionInfoPtr p = info; p; p = p->underlying) + { + Ice::IPConnectionInfoPtr ipInfo = ICE_DYNAMIC_CAST(Ice::IPConnectionInfo, p); + if(ipInfo) + { + return ipInfo; + } + } + return ICE_NULLPTR; +} + +} + void allTests(const Ice::CommunicatorPtr& communicator) { @@ -32,7 +51,7 @@ allTests(const Ice::CommunicatorPtr& communicator) cout << "testing connection information... " << flush; { - Ice::IPConnectionInfoPtr info = ICE_DYNAMIC_CAST(Ice::IPConnectionInfo, test->ice_getConnection()->getInfo()); + Ice::IPConnectionInfoPtr info = getIPConnectionInfo(test->ice_getConnection()->getInfo()); test(info->remotePort == 12030 || info->remotePort == 12031); // make sure we are connected to the proxy port. } cout << "ok" << endl; diff --git a/cpp/test/Ice/operations/Client.cpp b/cpp/test/Ice/operations/Client.cpp index 73b19851fb0..a000b049a77 100644 --- a/cpp/test/Ice/operations/Client.cpp +++ b/cpp/test/Ice/operations/Client.cpp @@ -17,7 +17,7 @@ using namespace std; int run(int, char**, const Ice::CommunicatorPtr& communicator, bool remote) -{ +{ Test::MyClassPrxPtr allTests(const Ice::CommunicatorPtr&); Test::MyClassPrxPtr myClass = allTests(communicator); @@ -67,8 +67,7 @@ main(int argc, char* argv[]) initData.properties = Ice::createProperties(argc, argv); initData.properties->setProperty("Ice.ThreadPool.Client.Size", "2"); initData.properties->setProperty("Ice.ThreadPool.Client.SizeWarn", "0"); - - initData.properties->setProperty("Ice.BatchAutoFlushSize", "100"); + initData.properties->setProperty("Ice.BatchAutoFlushSize", "100"); Ice::CommunicatorHolder ich = Ice::initialize(argc, argv, initData); RemoteConfig rc("Ice/operations", argc, argv, ich.communicator()); diff --git a/cpp/test/Ice/slicing/exceptions/AllTests.cpp b/cpp/test/Ice/slicing/exceptions/AllTests.cpp index 28e11dae7b4..b510a7f0c76 100644 --- a/cpp/test/Ice/slicing/exceptions/AllTests.cpp +++ b/cpp/test/Ice/slicing/exceptions/AllTests.cpp @@ -411,7 +411,7 @@ allTests(const Ice::CommunicatorPtr& communicator) { test(false); } - + #else CallbackPtr cb = new Callback; test->begin_baseAsBase( @@ -557,7 +557,7 @@ allTests(const Ice::CommunicatorPtr& communicator) #else CallbackPtr cb = new Callback; test->begin_knownDerivedAsKnownDerived( - newCallback_TestIntf_knownDerivedAsKnownDerived(cb, &Callback::response, + newCallback_TestIntf_knownDerivedAsKnownDerived(cb, &Callback::response, &Callback::exception_knownDerivedAsKnownDerived)); cb->check(); #endif @@ -604,7 +604,7 @@ allTests(const Ice::CommunicatorPtr& communicator) #else CallbackPtr cb = new Callback; test->begin_unknownIntermediateAsBase( - newCallback_TestIntf_unknownIntermediateAsBase(cb, &Callback::response, + newCallback_TestIntf_unknownIntermediateAsBase(cb, &Callback::response, &Callback::exception_unknownIntermediateAsBase)); cb->check(); #endif @@ -653,7 +653,7 @@ allTests(const Ice::CommunicatorPtr& communicator) #else CallbackPtr cb = new Callback; test->begin_knownIntermediateAsBase( - newCallback_TestIntf_knownIntermediateAsBase(cb, &Callback::response, + newCallback_TestIntf_knownIntermediateAsBase(cb, &Callback::response, &Callback::exception_knownIntermediateAsBase)); cb->check(); #endif @@ -704,7 +704,7 @@ allTests(const Ice::CommunicatorPtr& communicator) #else CallbackPtr cb = new Callback; test->begin_knownMostDerivedAsBase( - newCallback_TestIntf_knownMostDerivedAsBase(cb, &Callback::response, + newCallback_TestIntf_knownMostDerivedAsBase(cb, &Callback::response, &Callback::exception_knownMostDerivedAsBase)); cb->check(); #endif @@ -753,7 +753,7 @@ allTests(const Ice::CommunicatorPtr& communicator) #else CallbackPtr cb = new Callback; test->begin_knownIntermediateAsKnownIntermediate( - newCallback_TestIntf_knownIntermediateAsKnownIntermediate(cb, &Callback::response, + newCallback_TestIntf_knownIntermediateAsKnownIntermediate(cb, &Callback::response, &Callback::exception_knownIntermediateAsKnownIntermediate)); cb->check(); #endif @@ -804,7 +804,7 @@ allTests(const Ice::CommunicatorPtr& communicator) #else CallbackPtr cb = new Callback; test->begin_knownMostDerivedAsKnownIntermediate( - newCallback_TestIntf_knownMostDerivedAsKnownIntermediate(cb, &Callback::response, + newCallback_TestIntf_knownMostDerivedAsKnownIntermediate(cb, &Callback::response, &Callback::exception_knownMostDerivedAsKnownIntermediate)); cb->check(); #endif @@ -855,7 +855,7 @@ allTests(const Ice::CommunicatorPtr& communicator) #else CallbackPtr cb = new Callback; test->begin_knownMostDerivedAsKnownMostDerived( - newCallback_TestIntf_knownMostDerivedAsKnownMostDerived(cb, &Callback::response, + newCallback_TestIntf_knownMostDerivedAsKnownMostDerived(cb, &Callback::response, &Callback::exception_knownMostDerivedAsKnownMostDerived)); cb->check(); #endif @@ -904,7 +904,7 @@ allTests(const Ice::CommunicatorPtr& communicator) #else CallbackPtr cb = new Callback; test->begin_unknownMostDerived1AsBase( - newCallback_TestIntf_unknownMostDerived1AsBase(cb, &Callback::response, + newCallback_TestIntf_unknownMostDerived1AsBase(cb, &Callback::response, &Callback::exception_unknownMostDerived1AsBase)); cb->check(); #endif @@ -953,7 +953,7 @@ allTests(const Ice::CommunicatorPtr& communicator) #else CallbackPtr cb = new Callback; test->begin_unknownMostDerived1AsKnownIntermediate( - newCallback_TestIntf_unknownMostDerived1AsKnownIntermediate(cb, &Callback::response, + newCallback_TestIntf_unknownMostDerived1AsKnownIntermediate(cb, &Callback::response, &Callback::exception_unknownMostDerived1AsKnownIntermediate)); cb->check(); #endif @@ -1000,7 +1000,7 @@ allTests(const Ice::CommunicatorPtr& communicator) #else CallbackPtr cb = new Callback; test->begin_unknownMostDerived2AsBase( - newCallback_TestIntf_unknownMostDerived2AsBase(cb, &Callback::response, + newCallback_TestIntf_unknownMostDerived2AsBase(cb, &Callback::response, &Callback::exception_unknownMostDerived2AsBase)); cb->check(); #endif @@ -1072,11 +1072,6 @@ allTests(const Ice::CommunicatorPtr& communicator) catch(const Ice::OperationNotExistException&) { } - catch(const Ice::LocalException& ex) - { - cout << endl << "** OOPS" << endl << ex << endl; - test(false); - } catch(...) { test(false); diff --git a/cpp/test/IceSSL/configuration/AllTests.cpp b/cpp/test/IceSSL/configuration/AllTests.cpp index 3313424859a..65d4d031640 100644 --- a/cpp/test/IceSSL/configuration/AllTests.cpp +++ b/cpp/test/IceSSL/configuration/AllTests.cpp @@ -2,7 +2,7 @@ // // Copyright (c) 2003-2016 ZeroC, Inc. All rights reserved. // -// This copy of Ice is licensed to you under the terms described in the +// This copy of Ice is licensed to you under the terms dribed in the // ICE_LICENSE file included in this distribution. // // ********************************************************************** @@ -15,6 +15,9 @@ #ifdef __APPLE__ # include <sys/sysctl.h> +#if TARGET_OS_IPHONE != 0 +#include <IceSSL/Util.h> // For loadCertificateChain +#endif #endif #ifdef ICE_CPP11_MAPPING @@ -141,6 +144,83 @@ private: vector<PCCERT_CONTEXT> _certs; }; +#elif defined(__APPLE__) && TARGET_OS_IPHONE != 0 +class ImportCerts +{ +public: + + ImportCerts(const string& defaultDir, const char* certificates[]) + { + for(int i = 0; certificates[i] != 0; ++i) + { + string resolved; + if(IceSSL::checkPath(certificates[i], defaultDir, false, resolved)) + { + CFArrayRef certs = IceSSL::loadCertificateChain(resolved, "", "", "", "password", 0, 0); + SecIdentityRef identity = (SecIdentityRef)CFArrayGetValueAtIndex(certs, 0); + CFRetain(identity); + _identities.push_back(identity); + OSStatus err; + CFMutableDictionaryRef query; + + query = CFDictionaryCreateMutable(0, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + CFDictionarySetValue(query, kSecValueRef, identity); + if((err = SecItemAdd(query, 0))) + { + cerr << "failed to add identity " << certificates[i] << ": " << err << endl; + } + CFRelease(query); + + // query = CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + // CFDictionarySetValue(query, kSecClass, kSecClassCertificate); + // CFDictionarySetValue(query, kSecReturnRef, kCFBooleanTrue); + // CFDictionarySetValue(query, kSecMatchLimit, kSecMatchLimitAll); + // CFArrayRef array = 0; + // err = SecItemCopyMatching(query, (CFTypeRef*)&array); + // printf("Certificates\n"); + // for(int i = 0; i < CFArrayGetCount(array); ++i) + // { + // printf("Cert %d: %s\n", i, (new IceSSL::Certificate((SecCertificateRef)CFArrayGetValueAtIndex(array, i)))->toString().c_str()); + // } + // CFRelease(certs); + } + } + // Nothing to do. + } + + ~ImportCerts() + { + cleanup(); + } + + void cleanup() + { + CFMutableDictionaryRef query; + for(vector<SecIdentityRef>::const_iterator p = _identities.begin(); p != _identities.end(); ++p) + { + query = CFDictionaryCreateMutable(0, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + CFDictionarySetValue(query, kSecClass, kSecClassIdentity); + CFDictionarySetValue(query, kSecValueRef, *p); + SecItemDelete(query); + CFRelease(query); + + SecCertificateRef cert; + SecIdentityCopyCertificate(*p, &cert); + query = CFDictionaryCreateMutable(0, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + CFDictionarySetValue(query, kSecClass, kSecClassCertificate); + CFDictionarySetValue(query, kSecValueRef, cert); + SecItemDelete(query); + CFRelease(query); + + CFRelease(*p); + } + _identities.clear(); + } + +private: + + vector<SecIdentityRef> _identities; +}; #else class ImportCerts { @@ -197,6 +277,7 @@ public: { if(info->nativeCerts.size() > 0) { +#if !defined(__APPLE__) || TARGET_OS_IPHONE == 0 // // Subject alternative name // @@ -243,6 +324,7 @@ public: test(find(ipAddresses.begin(), ipAddresses.end(), "127.0.0.1") != ipAddresses.end()); test(find(emailAddresses.begin(), emailAddresses.end(), "issuer@zeroc.com") != emailAddresses.end()); } +#endif } _hadCert = info->nativeCerts.size() != 0; @@ -306,7 +388,8 @@ createClientProps(const Ice::PropertiesPtr& defaultProps, const string& defaultD { result->setProperty("IceSSL.Password", "password"); } - //result->setProperty("IceSSL.Trace.Security", "1"); +// result->setProperty("IceSSL.Trace.Security", "1"); +// result->setProperty("Ice.Trace.Network", "1"); #ifdef ICE_USE_SECURE_TRANSPORT ostringstream keychainName; keychainName << "../certs/keychain/client" << keychainN++ << ".keychain"; @@ -338,7 +421,8 @@ createServerProps(const Ice::PropertiesPtr& defaultProps, const string& defaultD { result["IceSSL.Password"] = "password"; } - //result["IceSSL.Trace.Security"] = "1"; +// result["Ice.Trace.Network"] = "1"; +// result["IceSSL.Trace.Security"] = "1"; #ifdef ICE_USE_SECURE_TRANSPORT ostringstream keychainName; keychainName << "../certs/keychain/server" << keychainN << ".keychain"; @@ -420,8 +504,8 @@ void verify(const IceSSL::CertificatePtr& cert, const IceSSL::CertificatePtr& ca cerr << endl; } -void -allTests(const CommunicatorPtr& communicator, const string& testDir, bool p12, bool shutdown) +Test::ServerFactoryPrxPtr +allTests(const CommunicatorPtr& communicator, const string& testDir, bool p12) { bool elCapitanUpdate2OrLower = false; #ifdef __APPLE__ @@ -441,14 +525,19 @@ allTests(const CommunicatorPtr& communicator, const string& testDir, bool p12, b } } #endif - - string factoryRef = "factory:tcp -p 12010"; + string endpt = getTestEndpoint(communicator, 0); + string factoryRef = "factory:" + endpt; ObjectPrxPtr base = communicator->stringToProxy(factoryRef); test(base); Test::ServerFactoryPrxPtr factory = ICE_CHECKED_CAST(Test::ServerFactoryPrx, base); string defaultHost = communicator->getProperties()->getProperty("Ice.Default.Host"); +#if !defined(__APPLE__) || TARGET_OS_IPHONE == 0 string defaultDir = testDir + "/../certs"; +#else + string defaultDir = "certs"; +#endif + Ice::PropertiesPtr defaultProps = communicator->getProperties(); #ifdef _WIN32 string sep = ";"; @@ -484,7 +573,7 @@ allTests(const CommunicatorPtr& communicator, const string& testDir, bool p12, b // // Anonymous cipher are not supported with SChannel // -#ifndef ICE_USE_SCHANNEL +#if !defined(ICE_USE_SCHANNEL) { InitializationData initData; initData.properties = createClientProps(defaultProps, defaultDir, defaultHost, p12); @@ -647,16 +736,22 @@ allTests(const CommunicatorPtr& communicator, const string& testDir, bool p12, b IceSSL::CertificatePtr serverCert = IceSSL::Certificate::load(defaultDir + "/s_rsa_ca1_pub.pem"); test(ICE_TARGET_EQUALS(IceSSL::Certificate::decode(serverCert->encode()), serverCert)); test(ICE_TARGET_EQUALS(serverCert, serverCert)); +#if !defined(__APPLE__) || TARGET_OS_IPHONE == 0 test(serverCert->checkValidity()); test(!serverCert->checkValidity(IceUtil::Time::seconds(0))); +#endif IceSSL::CertificatePtr caCert = IceSSL::Certificate::load(defaultDir + "/cacert1.pem"); + IceSSL::CertificatePtr caCert2 = IceSSL::Certificate::load(defaultDir + "/cacert2.pem"); test(ICE_TARGET_EQUALS(caCert, caCert)); +#if !defined(__APPLE__) || TARGET_OS_IPHONE == 0 test(caCert->checkValidity()); test(!caCert->checkValidity(IceUtil::Time::seconds(0))); +#endif test(!serverCert->verify(serverCert)); test(serverCert->verify(caCert)); + test(!serverCert->verify(caCert2)); test(caCert->verify(caCert)); info = ICE_DYNAMIC_CAST(IceSSL::NativeConnectionInfo, server->ice_getConnection()->getInfo()); @@ -669,9 +764,11 @@ allTests(const CommunicatorPtr& communicator, const string& testDir, bool p12, b test(!(ICE_TARGET_EQUALS(serverCert, info->nativeCerts[1]))); test(!(ICE_TARGET_EQUALS(caCert, info->nativeCerts[0]))); +#if !defined(__APPLE__) || TARGET_OS_IPHONE == 0 test(info->nativeCerts[0]->checkValidity() && info->nativeCerts[1]->checkValidity()); test(!info->nativeCerts[0]->checkValidity(IceUtil::Time::seconds(0)) && !info->nativeCerts[1]->checkValidity(IceUtil::Time::seconds(0))); +#endif test(info->nativeCerts[0]->verify(info->nativeCerts[1])); test(info->nativeCerts.size() == 2 && info->nativeCerts[0]->getSubjectDN() == serverCert->getSubjectDN() && @@ -874,8 +971,9 @@ allTests(const CommunicatorPtr& communicator, const string& testDir, bool p12, b { server->ice_ping(); } - catch(const LocalException&) + catch(const LocalException& ex) { + cerr << ex << endl; test(false); } fact->destroyServer(server); @@ -1589,10 +1687,12 @@ allTests(const CommunicatorPtr& communicator, const string& testDir, bool p12, b // // This should fail because the server's certificate is expired. // +#if !defined(__APPLE__) || TARGET_OS_IPHONE == 0 { IceSSL::CertificatePtr cert = IceSSL::Certificate::load(defaultDir + "/s_rsa_ca1_exp_pub.pem"); test(!cert->checkValidity()); } +#endif InitializationData initData; initData.properties = createClientProps(defaultProps, defaultDir, defaultHost, p12, "c_rsa_ca1", "cacert1"); @@ -1621,10 +1721,12 @@ allTests(const CommunicatorPtr& communicator, const string& testDir, bool p12, b // // This should fail because the client's certificate is expired. // +#if !defined(__APPLE__) || TARGET_OS_IPHONE == 0 { IceSSL::CertificatePtr cert = IceSSL::Certificate::load(defaultDir + "/c_rsa_ca1_exp_pub.pem"); test(!cert->checkValidity()); } +#endif initData.properties = createClientProps(defaultProps, defaultDir, defaultHost, p12, "c_rsa_ca1_exp", "cacert1"); comm = initialize(initData); @@ -2193,9 +2295,14 @@ allTests(const CommunicatorPtr& communicator, const string& testDir, bool p12, b cout << "ok" << endl; cout << "testing IceSSL.TrustOnly... " << flush; + // + // iOS support only provides access to the CN of the certificate so we + // can't check for other attributes + // { InitializationData initData; initData.properties = createClientProps(defaultProps, defaultDir, defaultHost, p12, "c_rsa_ca1", "cacert1"); + initData.properties->setProperty("IceSSL.TrustOnly", "CN=Server"); initData.properties->setProperty("IceSSL.TrustOnly", "C=US, ST=Florida, O=ZeroC\\, Inc.," "OU=Ice, emailAddress=info@zeroc.com, CN=Server"); CommunicatorPtr comm = initialize(initData); @@ -2568,7 +2675,7 @@ allTests(const CommunicatorPtr& communicator, const string& testDir, bool p12, b test(fact); Test::Properties d = createServerProps(defaultProps, defaultDir, defaultHost, p12, "s_rsa_ca1", "cacert1"); d["IceSSL.VerifyPeer"] = "0"; - d["IceSSL.TrustOnly"] = "C=US, ST=Florida, O=ZeroC\\, Inc.,OU=Ice, emailAddress=info@zeroc.com, CN=Client"; + d["IceSSL.TrustOnly"] = "CN=Client"; Test::ServerPrxPtr server = fact->createServer(d); try { @@ -2593,7 +2700,7 @@ allTests(const CommunicatorPtr& communicator, const string& testDir, bool p12, b Test::ServerFactoryPrxPtr fact = ICE_CHECKED_CAST(Test::ServerFactoryPrx, comm->stringToProxy(factoryRef)); test(fact); Test::Properties d = createServerProps(defaultProps, defaultDir, defaultHost, p12, "s_rsa_ca1", "cacert1"); - d["IceSSL.TrustOnly"] = "!C=US, ST=Florida, O=ZeroC\\, Inc.,OU=Ice, emailAddress=info@zeroc.com, CN=Client"; + d["IceSSL.TrustOnly"] = "!CN=Client"; d["IceSSL.VerifyPeer"] = "0"; Test::ServerPrxPtr server = fact->createServer(d); try @@ -3116,7 +3223,7 @@ allTests(const CommunicatorPtr& communicator, const string& testDir, bool p12, b cout << "testing IceSSL.FindCert... " << flush; const char* clientFindCertProperties[] = { - "SUBJECT:Client", +// "SUBJECT:Client", "LABEL:'Client'", "SUBJECTKEYID:'FC 5D 4F AB F0 6C 03 11 B8 F3 68 CF 89 54 92 3F F9 79 2A 06'", "SERIAL:02", @@ -3126,7 +3233,10 @@ allTests(const CommunicatorPtr& communicator, const string& testDir, bool p12, b const char* serverFindCertProperties[] = { +#if !defined(__APPLE__) || TARGET_OS_IPHONE == 0 + // iOS match on Subject DN isn't supported by SecItemCopyMatch "SUBJECT:Server", +#endif "LABEL:'Server'", "SUBJECTKEYID:'47 84 AE F9 F2 85 3D 99 30 6A 03 38 41 1A B9 EB C3 9C B5 4D'", "SERIAL:01", @@ -3139,7 +3249,10 @@ allTests(const CommunicatorPtr& communicator, const string& testDir, bool p12, b "nolabel", "unknownlabel:foo", "LABEL:", +#if !defined(__APPLE__) || TARGET_OS_IPHONE == 0 + // iOS match on Subject DN isn't supported by SecItemCopyMatch "SUBJECT:ServerX", +#endif "LABEL:'ServerX'", "SUBJECTKEYID:'a6 42 aa 17 04 41 86 56 67 e4 04 64 59 34 30 c7 4c 6b ef ff'", "SERIAL:04", @@ -3147,6 +3260,9 @@ allTests(const CommunicatorPtr& communicator, const string& testDir, bool p12, b 0 }; + const char* certificates[] = {"/s_rsa_ca1.p12", "/c_rsa_ca1.p12", 0}; + ImportCerts import(defaultDir, certificates); + for(int i = 0; clientFindCertProperties[i] != 0; i++) { InitializationData initData; @@ -3169,6 +3285,7 @@ allTests(const CommunicatorPtr& communicator, const string& testDir, bool p12, b d["IceSSL.Keychain"] = "../certs/Find.keychain"; d["IceSSL.KeychainPassword"] = "password"; d["IceSSL.FindCert"] = serverFindCertProperties[i]; + // // Use TrustOnly to ensure the peer has pick the expected certificate. // @@ -3198,6 +3315,7 @@ allTests(const CommunicatorPtr& communicator, const string& testDir, bool p12, b try { CommunicatorPtr comm = initialize(initData); + printf("failed %s", failFindCertProperties[i]); test(false); } catch(const PluginInitializationException&) @@ -3247,11 +3365,11 @@ allTests(const CommunicatorPtr& communicator, const string& testDir, bool p12, b comm = initialize(initData); p = comm->stringToProxy("dummy:wss -h demo.zeroc.com -p 5064"); - IceSSL::WSSConnectionInfoPtr info; try { - info = ICE_DYNAMIC_CAST(IceSSL::WSSConnectionInfo, p->ice_getConnection()->getInfo()); - test(info->verified); + Ice::WSConnectionInfoPtr info = ICE_DYNAMIC_CAST(Ice::WSConnectionInfo, p->ice_getConnection()->getInfo()); + IceSSL::ConnectionInfoPtr sslInfo = ICE_DYNAMIC_CAST(IceSSL::ConnectionInfo, info->underlying); + test(sslInfo->verified); } catch(const Ice::LocalException& ex) { @@ -3261,9 +3379,5 @@ allTests(const CommunicatorPtr& communicator, const string& testDir, bool p12, b } cout << "ok" << endl; #endif - - if(shutdown) - { - factory->shutdown(); - } + return factory; } diff --git a/cpp/test/IceSSL/configuration/Client.cpp b/cpp/test/IceSSL/configuration/Client.cpp index 14538e7beac..68d3ad936e1 100644 --- a/cpp/test/IceSSL/configuration/Client.cpp +++ b/cpp/test/IceSSL/configuration/Client.cpp @@ -9,26 +9,51 @@ #include <Ice/Ice.h> #include <IceSSL/IceSSL.h> +#include <TestCommon.h> +#include <Test.h> + +DEFINE_TEST("client") using namespace std; int run(int argc, char* argv[], const Ice::CommunicatorPtr& communicator) { + string testdir; +#if TARGET_OS_IPHONE == 0 if(argc < 2) { cerr << "Usage: " << argv[0] << " testdir" << endl; return 1; } + testdir = argv[1]; +#endif - void allTests(const Ice::CommunicatorPtr&, const string&, bool, bool); - - cerr << "testing with PKCS12 certificates..." << endl; - allTests(communicator, argv[1], true, false); - cerr << "testing with PEM certificates..." << endl; - allTests(communicator, argv[1], false, true); + Test::ServerFactoryPrxPtr allTests(const Ice::CommunicatorPtr&, const string&, bool); + try + { + cerr << "testing with PKCS12 certificates..." << endl; + Test::ServerFactoryPrxPtr factory = allTests(communicator, testdir, true); +#if !defined(__APPLE__) || TARGET_OS_IPHONE == 0 + cerr << "testing with PEM certificates..." << endl; + factory = allTests(communicator, testdir, false); +#endif + if(factory) + { + factory->shutdown(); + } + } + catch(const IceSSL::CertificateReadException& ex) + { + cout << "couldn't read certificate: " << ex.reason << endl; + } + catch(const std::exception& ex) + { + cout << "unexpected exception: " << ex.what() << endl; + } return EXIT_SUCCESS; + } int diff --git a/cpp/test/IceSSL/configuration/Makefile.mk b/cpp/test/IceSSL/configuration/Makefile.mk index 92098e429b6..9eb4e1b4c75 100644 --- a/cpp/test/IceSSL/configuration/Makefile.mk +++ b/cpp/test/IceSSL/configuration/Makefile.mk @@ -9,4 +9,8 @@ $(test)_dependencies = IceSSL Ice TestCommon +# Need to load certificates with functions from src/IceSSL/Util.h +$(test)[iphoneos]_cppflags := -Isrc +$(test)[iphonesimulator]_cppflags := -Isrc + tests += $(test) diff --git a/cpp/test/IceSSL/configuration/Server.cpp b/cpp/test/IceSSL/configuration/Server.cpp index 5ed1e401b15..6a1f98614dd 100644 --- a/cpp/test/IceSSL/configuration/Server.cpp +++ b/cpp/test/IceSSL/configuration/Server.cpp @@ -9,18 +9,21 @@ #include <Ice/Ice.h> #include <TestI.h> +#include <TestCommon.h> + +DEFINE_TEST("server") using namespace std; int run(int, char**, const Ice::CommunicatorPtr& communicator) { - communicator->getProperties()->setProperty("TestAdapter.Endpoints", "tcp -p 12010"); + communicator->getProperties()->setProperty("TestAdapter.Endpoints", getTestEndpoint(communicator, 0)); Ice::ObjectAdapterPtr adapter = communicator->createObjectAdapter("TestAdapter"); Ice::Identity id = communicator->stringToIdentity("factory"); adapter->add(ICE_MAKE_SHARED(ServerFactoryI), id); adapter->activate(); - + TEST_READY communicator->waitForShutdown(); return EXIT_SUCCESS; } diff --git a/cpp/test/IceSSL/configuration/TestI.cpp b/cpp/test/IceSSL/configuration/TestI.cpp index 7723da865b3..39b78d02712 100644 --- a/cpp/test/IceSSL/configuration/TestI.cpp +++ b/cpp/test/IceSSL/configuration/TestI.cpp @@ -45,7 +45,8 @@ ServerI::checkCert(ICE_IN(string) subjectDN, ICE_IN(string) issuerDN, const Ice: test(info->verified); test(info->nativeCerts.size() == 2 && info->nativeCerts[0]->getSubjectDN() == IceSSL::DistinguishedName(subjectDN) && - info->nativeCerts[0]->getIssuerDN() == IceSSL::DistinguishedName(issuerDN)); + info->nativeCerts[0]->getIssuerDN() == IceSSL::DistinguishedName(issuerDN) + ); } catch(const Ice::LocalException&) { diff --git a/cpp/test/ios/C++ Test Suite.xcodeproj/project.pbxproj b/cpp/test/ios/C++ Test Suite.xcodeproj/project.pbxproj index 497f4f097c9..f254b1f0bef 100755 --- a/cpp/test/ios/C++ Test Suite.xcodeproj/project.pbxproj +++ b/cpp/test/ios/C++ Test Suite.xcodeproj/project.pbxproj @@ -66,6 +66,9 @@ 144B483C1A78F71F00C0E06B /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 344126370FD8E8EA00C8D69C /* CFNetwork.framework */; }; 144B483D1A78F71F00C0E06B /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34E396620FF1D71400FBACD6 /* CoreGraphics.framework */; }; 1450A10C1ABC5E9C00A71895 /* client.p12 in Resources */ = {isa = PBXBuildFile; fileRef = 1450A10B1ABC5E9C00A71895 /* client.p12 */; }; + 14D7F3391D0ED442008C79C9 /* certs in Resources */ = {isa = PBXBuildFile; fileRef = 14D7F3381D0ED442008C79C9 /* certs */; }; + 14D7F33A1D0ED442008C79C9 /* certs in Resources */ = {isa = PBXBuildFile; fileRef = 14D7F3381D0ED442008C79C9 /* certs */; }; + 14D7F33B1D0ED442008C79C9 /* certs in Resources */ = {isa = PBXBuildFile; fileRef = 14D7F3381D0ED442008C79C9 /* certs */; }; D837179F1BFFC25C005D65BC /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D8842ED91BFF87E700A8B607 /* Images.xcassets */; }; D8842EDA1BFF87E700A8B607 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D8842ED91BFF87E700A8B607 /* Images.xcassets */; }; D8842EDC1BFF885600A8B607 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D8842EDB1BFF885600A8B607 /* Default-568h@2x.png */; }; @@ -79,6 +82,7 @@ 1450A10B1ABC5E9C00A71895 /* client.p12 */ = {isa = PBXFileReference; lastKnownFileType = file; name = client.p12; path = ../../../../ice/certs/client.p12; sourceTree = "<group>"; }; 1477FACD1A652B7E00BC2890 /* C++98 Test Suite-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "C++98 Test Suite-Info.plist"; sourceTree = "<group>"; }; 148668D31B6BAFD300234C12 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; }; + 14D7F3381D0ED442008C79C9 /* certs */ = {isa = PBXFileReference; lastKnownFileType = folder; name = certs; path = ../IceSSL/certs; sourceTree = "<group>"; }; 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 28AD733E0D9D9553002E5188 /* MainWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MainWindow.xib; sourceTree = "<group>"; }; @@ -198,6 +202,7 @@ 29B97317FDCFA39411CA2CEA /* Resources */ = { isa = PBXGroup; children = ( + 14D7F3381D0ED442008C79C9 /* certs */, 342EBA8A0E926F90000051FA /* cacert.der */, 1450A10B1ABC5E9C00A71895 /* client.p12 */, D8842EDB1BFF885600A8B607 /* Default-568h@2x.png */, @@ -328,6 +333,7 @@ 14103B141CFC5E0E0097DE5A /* Default-568h@2x.png in Resources */, 14103B151CFC5E0E0097DE5A /* client.p12 in Resources */, 14103B161CFC5E0E0097DE5A /* cacert.der in Resources */, + 14D7F33B1D0ED442008C79C9 /* certs in Resources */, 14103B171CFC5E0E0097DE5A /* TestSelect-iPad.xib in Resources */, 14103B181CFC5E0E0097DE5A /* MainWindow-iPad.xib in Resources */, 14103B191CFC5E0E0097DE5A /* TestView.xib in Resources */, @@ -339,6 +345,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 14D7F33A1D0ED442008C79C9 /* certs in Resources */, 142B83841B6BA7A600E28347 /* MainWindow.xib in Resources */, D837179F1BFFC25C005D65BC /* Images.xcassets in Resources */, 142B83851B6BA7A600E28347 /* TestSelect.xib in Resources */, @@ -363,6 +370,7 @@ D8842EDC1BFF885600A8B607 /* Default-568h@2x.png in Resources */, 1450A10C1ABC5E9C00A71895 /* client.p12 in Resources */, 144B482B1A78F71F00C0E06B /* cacert.der in Resources */, + 14D7F3391D0ED442008C79C9 /* certs in Resources */, 144B482C1A78F71F00C0E06B /* TestSelect-iPad.xib in Resources */, 144B482D1A78F71F00C0E06B /* MainWindow-iPad.xib in Resources */, 144B482E1A78F71F00C0E06B /* TestView.xib in Resources */, @@ -399,7 +407,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "#\n# We don't use a CopyFile build phase here to copy the test bundles because the test\n# bundles are located in different location depending on the platform. This script\n# copies the bundles if updated and sign them.\n#\nFRAMEWORKS_PATH=\"${TARGET_BUILD_DIR}\"/\"${FRAMEWORKS_FOLDER_PATH}\"\ncd \"Bundles-${PLATFORM_NAME}\"\nif [ ! -d \"$FRAMEWORKS_PATH\" ]; then\n mkdir -p \"$FRAMEWORKS_PATH\"\nfi;\nfor i in `ls -d *.bundle`;\ndo\n if [ ! -d \"$FRAMEWORKS_PATH/$i\" -o \"$i\" -nt \"$FRAMEWORKS_PATH/$i\" ];\n then\n echo \"Copying $i\";\n cp -rf $i \"$FRAMEWORKS_PATH\"/;\n fi;\ndone\n\n"; + shellScript = "#\n# We don't use a CopyFile build phase here to copy the test bundles because the test\n# bundles are located in different location depending on the platform. This script\n# copies the bundles if updated and sign them.\n#\nFRAMEWORKS_PATH=\"${TARGET_BUILD_DIR}\"/\"${FRAMEWORKS_FOLDER_PATH}\"\ncd \"Bundles-${PLATFORM_NAME}\"\nif [ ! -d \"$FRAMEWORKS_PATH\" ]; then\n mkdir -p \"$FRAMEWORKS_PATH\"\nfi;\nfor i in `ls -d */*.bundle`;\ndo\n if [ ! -d \"$FRAMEWORKS_PATH/$i\" -o \"$i\" -nt \"$FRAMEWORKS_PATH/$i\" ];\n then\n echo \"Copying $i\";\n mkdir -p \"$FRAMEWORKS_PATH/$(dirname $i)\"\n cp -rf $i \"$FRAMEWORKS_PATH/$(dirname $i)\"\n fi;\ndone\n\n"; }; 144B488F1A78F71F00C0E06B /* Run Script */ = { isa = PBXShellScriptBuildPhase; diff --git a/cpp/test/ios/Classes/AppDelegate.mm b/cpp/test/ios/Classes/AppDelegate.mm index 6f8f217bc4a..ac7e99dcaeb 100644 --- a/cpp/test/ios/Classes/AppDelegate.mm +++ b/cpp/test/ios/Classes/AppDelegate.mm @@ -65,6 +65,7 @@ static const struct TestData alltests[] = { @"metrics", @"Ice_metrics", @"client.bundle", @"server.bundle", 0, 0, false, false, false, false, true }, { @"enums", @"Ice_enums", @"client.bundle", @"server.bundle", 0, 0, true, true, false, true, true }, { @"services", @"Ice_services", @"client.bundle", 0, 0, 0, true, true, false, false, true }, +{ @"configuration", @"IceSSL_configuration", @"client.bundle", @"server.bundle", 0, 0, false, false, false, false, true }, }; @implementation AppDelegate diff --git a/cpp/test/uwp/MainPage.xaml.cpp b/cpp/test/uwp/MainPage.xaml.cpp index 303174816cc..5561f5b25c1 100644 --- a/cpp/test/uwp/MainPage.xaml.cpp +++ b/cpp/test/uwp/MainPage.xaml.cpp @@ -796,6 +796,7 @@ MainPage::MainPage() : _messages(ref new Vector<String^>()) { InitializeComponent(); + Ice::registerIceSSL(); } void |