Преглед изворни кода

HPCC-17572 Roxiepipe SSL support

Signed-off-by: Mark Kelly <mark.kelly@lexisnexisrisk.com>
Mark Kelly пре 8 година
родитељ
комит
b8c7d6e36b

+ 13 - 1
roxie/roxiepipe/CMakeLists.txt

@@ -29,12 +29,18 @@ set (    SRCS
          roxiepipe.cpp 
     )
 
-include_directories ( 
+include_directories (
          ./../../system/include 
          ./../../system/jlib 
          ./../../roxie/roxie
     )
 
+IF (USE_OPENSSL)
+    include_directories (
+         ./../../system/security/securesocket
+    )
+ENDIF()
+
 ADD_DEFINITIONS( -D_CONSOLE )
 
 HPCC_ADD_EXECUTABLE ( roxiepipe ${SRCS} )
@@ -43,3 +49,9 @@ target_link_libraries ( roxiepipe
          jlib
     )
 
+IF (USE_OPENSSL)
+    target_link_libraries ( roxiepipe
+         securesocket
+    )
+ENDIF()
+

+ 29 - 3
roxie/roxiepipe/roxiepipe.cpp

@@ -25,6 +25,9 @@
 #include "jmisc.hpp"
 #include "jqueue.tpp"
 #include "roxie.hpp"
+#ifdef _USE_OPENSSL
+# include "securesocket.hpp"
+#endif
 
 static int in_width = 0;
 static int out_width = 1;
@@ -40,11 +43,12 @@ static int readTimeout = 300;
 static Mutex readMutex;
 static Mutex writeMutex;
 static StringBuffer hosts;
-static ISmartSocketFactory *smartSocketFactory;
+static ISmartSocketFactory *smartSocketFactory = nullptr;
 static bool Aborting = false;
 static StringBuffer fatalError;
 static CriticalSection fatalErrorSect;
 
+static bool useSSL = false;
 
 interface IReceivedRoxieException : extends IException
 {
@@ -69,7 +73,6 @@ private:
 };
 
 
-
 class RoxieThread : public Thread
 {
 private:
@@ -445,6 +448,15 @@ public:
     }
 };
 
+MODULE_INIT(INIT_PRIORITY_STANDARD)
+{
+    return true;
+}
+
+MODULE_EXIT()
+{
+    ::Release(smartSocketFactory);
+}
 
 int main(int argc, char *argv[])
 {
@@ -571,6 +583,15 @@ int main(int argc, char *argv[])
             DebugBreak();
         }
 #endif
+        else if (stricmp(argv[i], "-ssl") == 0)
+        {
+#ifdef _USE_OPENSSL
+            useSSL = true;
+#else
+            fatalError.append("-ssl argument not supported : OpenSSL disabled in build");
+            break;
+#endif
+        }
         else
         {
             fatalError.appendf("Unknown/unexpected parameter %s", argv[i]);
@@ -622,7 +643,12 @@ int main(int argc, char *argv[])
 
             try
             {
-                smartSocketFactory = createSmartSocketFactory(hosts.str(), retryMode);
+#ifdef _USE_OPENSSL
+                if (useSSL)
+                    smartSocketFactory = createSecureSmartSocketFactory(hosts.str(), retryMode);
+                else
+#endif
+                    smartSocketFactory = createSmartSocketFactory(hosts.str(), retryMode);
             }
             catch (ISmartSocketException *e)
             {

+ 14 - 34
system/jlib/jsmartsock.cpp

@@ -95,33 +95,7 @@ private:
 };
 
 
-class jlib_decl CSmartSocket: implements ISmartSocket, public CInterface
-{
-    ISocket *sock;
-    SocketEndpoint ep;
-    CSmartSocketFactory *factory;
-
-public:
-    IMPLEMENT_IINTERFACE;
-
-    CSmartSocket(ISocket *_sock, SocketEndpoint &_ep, CSmartSocketFactory *_factory);
-    ~CSmartSocket();
-
-    // ISmartSocket
-    ISocket *querySocket() { return (sock); }
-
-    // subset of ISocket
-    void read(void* buf, size32_t min_size, size32_t max_size, size32_t &size_read,
-                        unsigned timeout = WAIT_FOREVER);
-    void read(void* buf, size32_t size);
-
-    size32_t write(void const* buf, size32_t size);
-
-    void close();
-};
-
-
-CSmartSocket::CSmartSocket(ISocket *_sock, SocketEndpoint &_ep, CSmartSocketFactory *_factory) : sock(_sock), ep(_ep), factory(_factory)
+CSmartSocket::CSmartSocket(ISocket *_sock, SocketEndpoint &_ep, ISmartSocketFactory *_factory) : sock(_sock), ep(_ep), factory(_factory)
 {
 };
 
@@ -305,14 +279,13 @@ SocketEndpoint& CSmartSocketFactory::nextEndpoint()
     return (ss->ep);
 }
 
-ISmartSocket *CSmartSocketFactory::connect_timeout( unsigned timeoutms)
+ISocket *CSmartSocketFactory::connect_sock(unsigned timeoutms, SmartSocketEndpoint *&ss, SocketEndpoint &ep)
 {
-    SmartSocketEndpoint *ss = nextSmartEndpoint();
+    ss = nextSmartEndpoint();
     if (!ss)
         throw createSmartSocketException(0, "smartsocket failed to get nextEndpoint");
 
-    ISocket *sock = NULL;
-    SocketEndpoint ep;
+    ISocket *sock = nullptr;
     try 
     {
         {
@@ -324,12 +297,10 @@ ISmartSocket *CSmartSocketFactory::connect_timeout( unsigned timeoutms)
             sock = ISocket::connect_timeout(ep, timeoutms);
         else
             sock = ISocket::connect(ep);
-
-        return new CSmartSocket(sock, ep, this);
     }
     catch (IException *e)
     {
-        StringBuffer s("CSmartSocketFactory::connect ");
+        StringBuffer s("CSmartSocketFactory::connect_sock ");
         ep.getUrlStr(s);
         EXCLOG(e,s.str());
         ss->status=false;
@@ -337,6 +308,15 @@ ISmartSocket *CSmartSocketFactory::connect_timeout( unsigned timeoutms)
             sock->Release();
         throw;
     }
+    return sock;
+}
+
+ISmartSocket *CSmartSocketFactory::connect_timeout(unsigned timeoutms)
+{
+    SocketEndpoint ep;
+    SmartSocketEndpoint *ss = nullptr;
+    Owned<ISocket> sock = connect_sock(timeoutms, ss, ep);
+    return new CSmartSocket(sock.getClear(), ep, this);
 }
 
 ISmartSocket *CSmartSocketFactory::connect()

+ 1 - 1
system/jlib/jsmartsock.hpp

@@ -21,7 +21,6 @@
 
 #include "jsocket.hpp"
 
-
 interface jlib_decl ISmartSocket : extends IInterface
 {
     // unique to ISmartSocket
@@ -69,6 +68,7 @@ interface jlib_thrown_decl ISmartSocketException : extends IException
 
 jlib_decl ISmartSocketFactory *createSmartSocketFactory(const char *_socklist, bool _retry = false, unsigned _retryInterval = 60, unsigned _dnsInterval = (unsigned) -1);
 
+jlib_decl ISmartSocketException *createSmartSocketException(int errorCode, const char *msg);
 
 #endif
 

+ 25 - 1
system/jlib/jsmartsock.ipp

@@ -84,7 +84,8 @@ public:
 
     ISmartSocket *connect();
 
-    ISmartSocket *connect_timeout( unsigned timeoutms = 0);
+    ISocket *connect_sock(unsigned timeoutms, SmartSocketEndpoint *&ss, SocketEndpoint &ep);
+    virtual ISmartSocket *connect_timeout(unsigned timeoutms = 0);
 
     ISmartSocket *connectNextAvailableSocket();
 
@@ -117,5 +118,28 @@ private:
     StringAttr msg;
 };
 
+class jlib_decl CSmartSocket: public CSimpleInterfaceOf<ISmartSocket>
+{
+public:
+    ISocket *sock;
+    SocketEndpoint ep;
+    ISmartSocketFactory *factory;
+
+    CSmartSocket(ISocket *_sock, SocketEndpoint &_ep, ISmartSocketFactory *_factory);
+    virtual ~CSmartSocket();
+
+    // ISmartSocket
+    virtual ISocket *querySocket() override { return sock; }
+
+    // subset of ISocket
+    virtual void read(void* buf, size32_t min_size, size32_t max_size, size32_t &size_read,
+                        unsigned timeout = WAIT_FOREVER) override;
+    virtual void read(void* buf, size32_t size) override;
+
+    virtual size32_t write(void const* buf, size32_t size) override;
+
+    virtual void close() override;
+};
+
 #endif
 

+ 37 - 0
system/security/securesocket/securesocket.cpp

@@ -58,6 +58,7 @@
 #include <openssl/conf.h>
 #include <openssl/x509v3.h>
 
+#include "jsmartsock.ipp"
 #include "securesocket.hpp"
 
 Owned<ISecureSocketContext> server_securesocket_context;
@@ -1641,3 +1642,39 @@ SECURESOCKET_API int signCertificate(const char* csr, const char* ca_certificate
 }
 
 }
+
+class CSecureSmartSocketFactory : public CSmartSocketFactory
+{
+public:
+    Owned<ISecureSocketContext> secureContext;
+
+    CSecureSmartSocketFactory(const char *_socklist, bool _retry, unsigned _retryInterval, unsigned _dnsInterval) : CSmartSocketFactory(_socklist, _retry, _retryInterval, _dnsInterval)
+    {
+        secureContext.setown(createSecureSocketContext(ClientSocket));
+    }
+
+    virtual ISmartSocket *connect_timeout(unsigned timeoutms) override
+    {
+        SocketEndpoint ep;
+        SmartSocketEndpoint *ss = nullptr;
+        Owned<ISecureSocket> ssock;
+        Owned<ISocket> sock = connect_sock(timeoutms, ss, ep);
+        try
+        {
+            ssock.setown(secureContext->createSecureSocket(sock.getClear()));
+            // secure_connect may also DBGLOG() errors ...
+            ssock->secure_connect();
+        }
+        catch (IException *e)
+        {
+            ss->status = false;
+            throw;
+        }
+        return new CSmartSocket(ssock.getClear(), ep, this);
+    }
+};
+
+ISmartSocketFactory *createSecureSmartSocketFactory(const char *_socklist, bool _retry, unsigned _retryInterval, unsigned _dnsInterval)
+{
+    return new CSecureSmartSocketFactory(_socklist, _retry, _retryInterval, _dnsInterval);
+}

+ 3 - 0
system/security/securesocket/securesocket.hpp

@@ -30,6 +30,7 @@
 
 #include "jsocket.hpp"
 #include "jptree.hpp"
+#include "jsmartsock.hpp"
 
 #define SSLIB "securesocket"
 
@@ -89,5 +90,7 @@ SECURESOCKET_API ICertificate *createCertificate();
 SECURESOCKET_API int signCertificate(const char* csr, const char* ca_certificate, const char* ca_privkey, const char* ca_passphrase, int days, StringBuffer& certificate);
 };
 
+SECURESOCKET_API ISmartSocketFactory *createSecureSmartSocketFactory(const char *_socklist, bool _retry = false, unsigned _retryInterval = 60, unsigned _dnsInterval = (unsigned) -1);
+
 #endif