summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjwh1 <jwh1@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1999-07-21 21:26:37 +0000
committerjwh1 <jwh1@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1999-07-21 21:26:37 +0000
commitcf4b3d804c96942b14d6a247827eb39d027fd208 (patch)
treec9dc6f60aad359c7a845c97a7c32ce62a7a3c1d1
parentaff4123c1793ff5d244f33b9836064395ca4574c (diff)
downloadATCD-cf4b3d804c96942b14d6a247827eb39d027fd208.tar.gz
*** empty log message ***
-rw-r--r--ace/Secure_SOCK_Acceptor.cpp165
-rw-r--r--ace/Secure_SOCK_Acceptor.h125
-rw-r--r--ace/Secure_SOCK_Connector.cpp251
-rw-r--r--ace/Secure_SOCK_Connector.h186
-rw-r--r--ace/Secure_SOCK_Stream.cpp777
-rw-r--r--ace/Secure_SOCK_Stream.h204
6 files changed, 1708 insertions, 0 deletions
diff --git a/ace/Secure_SOCK_Acceptor.cpp b/ace/Secure_SOCK_Acceptor.cpp
new file mode 100644
index 00000000000..d164e4f0671
--- /dev/null
+++ b/ace/Secure_SOCK_Acceptor.cpp
@@ -0,0 +1,165 @@
+// Secure_SOCK_Acceptor.cpp
+// $Id$
+#define ACE_BUILD_DLL
+#include "Secure_SOCK_Acceptor.h"
+
+#define ACE_HAS_OPENSSL
+#if defined (ACE_HAS_OPENSSL)
+
+#include <ace/Synch.h>
+#include <openssl/err.h>
+
+ACE_ALLOC_HOOK_DEFINE(ACE_Secure_SOCK_Acceptor)
+
+// Do nothing routine for constructor.
+
+ACE_Secure_SOCK_Acceptor::ACE_Secure_SOCK_Acceptor (void)
+{
+ ACE_TRACE ("ACE_Secure_SOCK_Acceptor::ACE_Secure_SOCK_Acceptor");
+}
+
+ACE_Secure_SOCK_Acceptor::ACE_Secure_SOCK_Acceptor (const ACE_Addr &local_sap,
+ int reuse_addr,
+ int protocol_family,
+ int backlog,
+ int protocol)
+ : acceptor_ (local_sap, reuse_addr, protocol_family, backlog, protocol)
+{
+ ACE_TRACE ("ACE_Secure_SOCK_Acceptor::ACE_Secure_SOCK_Acceptor");
+}
+// Performs the timed accept operation.
+
+ACE_Secure_SOCK_Acceptor::ACE_Secure_SOCK_Acceptor (const ACE_Addr &local_sap,
+ ACE_Protocol_Info *protocolinfo,
+ ACE_SOCK_GROUP g,
+ u_long flags,
+ int reuse_addr,
+ int protocol_family,
+ int backlog = ACE_DEFAULT_BACKLOG,
+ int protocol = 0)
+ : acceptor_ (local_sap, protocolinfo, g, flags, reuse_addr, protocol_family, backlog, protocol)
+{
+ ACE_TRACE ("ACE_Secure_SOCK_Acceptor::ACE_Secure_SOCK_Acceptor");
+}
+
+int
+ACE_Secure_SOCK_Acceptor::open (const ACE_Addr &local_sap,
+ int reuse_addr,
+ int protocol_family,
+ int backlog,
+ int protocol)
+{
+ ACE_TRACE ("ACE_Secure_SOCK_Acceptor::open");
+ return acceptor_.open (local_sap,
+ reuse_addr,
+ protocol_family,
+ backlog,
+ protocol);
+}
+
+ACE_Secure_SOCK_Acceptor::~ACE_Secure_SOCK_Acceptor (void)
+{
+ ACE_TRACE ("ACE_Secure_SOCK_Acceptor::~ACE_Secure_SOCK_Acceptor");
+}
+
+// General purpose routine for accepting new connections.
+int
+ACE_Secure_SOCK_Acceptor::accept (ACE_Secure_SOCK_Stream &new_stream,
+ ACE_Addr *remote_addr,
+ ACE_Time_Value *timeout,
+ int restart,
+ int reset_new_handle) const
+{
+ ACE_TRACE ("ACE_Secure_SOCK_Acceptor::accept");
+ shared_ssl_init_one (new_stream);
+ if (acceptor_.accept (new_stream.peer (),
+ remote_addr,
+ timeout,
+ restart,
+ reset_new_handle) == -1) {
+ return -1;
+ }
+ return shared_ssl_init_two (new_stream);
+}
+
+int
+ACE_Secure_SOCK_Acceptor::accept (ACE_Secure_SOCK_Stream &new_stream,
+ ACE_Accept_QoS_Params qos_params,
+ ACE_Addr *remote_addr,
+ ACE_Time_Value *timeout,
+ int restart,
+ int reset_new_handle) const
+{
+ ACE_TRACE ("ACE_Secure_SOCK_Acceptor::accept");
+ shared_ssl_init_one (new_stream);
+ if (acceptor_.accept (new_stream.peer (),
+ qos_params,
+ remote_addr,
+ timeout,
+ restart,
+ reset_new_handle) == -1) {
+ return -1;
+ }
+ return shared_ssl_init_two (new_stream);
+}
+
+int
+ACE_Secure_SOCK_Acceptor::get_local_addr (ACE_Addr &addr) const
+{
+ ACE_TRACE ("ACE_SECURE_SOCK_Acceptor::get_local_addr");
+ return acceptor_.get_local_addr (addr);
+}
+
+void
+ACE_Secure_SOCK_Acceptor::dump (void) const
+{
+ ACE_TRACE ("ACE_Secure_SOCK_Acceptor::dump");
+ acceptor_.dump ();
+}
+
+#define HOME "./"
+/* Make these what you want for cert & key files */
+#define CERTF HOME "jwh1.cert"
+#define KEYF HOME "key"
+
+#define CHK_NULL(x) if ((x)==NULL) exit (1)
+#define CHK_ERR(err,s) if ((err)==-1) { perror(s); exit(1); }
+#define CHK_SSL(err) if ((err)==-1) { ERR_print_errors_fp(stderr); exit(2);}
+
+int
+ACE_Secure_SOCK_Acceptor::shared_ssl_init_one (ACE_Secure_SOCK_Stream& new_stream) const{
+ SSL_load_error_strings ();
+ SSL_library_init ();
+ SSL_METHOD* meth = SSLv23_server_method ();
+ SSL_CTX* ctx = SSL_CTX_new (meth);
+ if (!ctx) {
+ ERR_print_errors_fp (stderr);
+ exit (2);
+ }
+
+ if (SSL_CTX_use_certificate_file (ctx, CERTF, SSL_FILETYPE_PEM) <= 0) {
+ ERR_print_errors_fp (stderr);
+ exit (3);
+ }
+ if (SSL_CTX_use_PrivateKey_file (ctx, KEYF, SSL_FILETYPE_PEM) <= 0) {
+ ERR_print_errors_fp (stderr);
+ exit(4);
+ }
+
+ if (!SSL_CTX_check_private_key (ctx)) {
+ fprintf (stderr,"Private key does not match the certificate public key\n");
+ exit (5);
+ }
+
+ new_stream.session (SSL_new (ctx)); CHK_NULL(new_stream.session ());
+ return 0;
+}
+
+int
+ACE_Secure_SOCK_Acceptor::shared_ssl_init_two (ACE_Secure_SOCK_Stream& new_stream) const{
+ SSL_set_fd (new_stream.session (), new_stream.get_handle ());
+ int err = SSL_accept (new_stream.session ()); CHK_SSL (err);
+ return 0;
+}
+
+#endif /* defined (ACE_HAS_OPENSSL) */
diff --git a/ace/Secure_SOCK_Acceptor.h b/ace/Secure_SOCK_Acceptor.h
new file mode 100644
index 00000000000..287d1a27d26
--- /dev/null
+++ b/ace/Secure_SOCK_Acceptor.h
@@ -0,0 +1,125 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// ace
+//
+// = FILENAME
+// Secure_SOCK_Acceptor.h
+//
+// = AUTHOR
+// John Heitmann
+//
+// ============================================================================
+
+#define ACE_HAS_OPENSSL
+#if defined (ACE_HAS_OPENSSL)
+
+#ifndef ACE_SECURE_SOCK_ACCEPTOR_H
+#define ACE_SECURE_SOCK_ACCEPTOR_H
+
+#include "Secure_SOCK_Stream.h"
+#include <ace/SOCK_Acceptor.h>
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+class ACE_Export ACE_Secure_SOCK_Acceptor
+{
+ // = TITLE
+ // Defines a factory that creates new <ACE_Secure_SOCK_Stream>s passively.
+ //
+ // = DESCRIPTION
+ // The <ACE_Secure_SOCK_Acceptor> has its own <ACE_SOCK_Acceptor> which
+ // handles virtually all of the socket acceptance. This class is a wrapper
+ // which only adds the ssl acceptance.
+public:
+ // = Initialization and termination methods.
+ ACE_Secure_SOCK_Acceptor (void);
+ // Default constructor.
+
+ ACE_Secure_SOCK_Acceptor (const ACE_Addr &local_sap,
+ int reuse_addr = 0,
+ int protocol_family = PF_INET,
+ int backlog = ACE_DEFAULT_BACKLOG,
+ int protocol = 0);
+ // Initiate a passive mode ssl/BSD-style acceptor socket.
+ // <local_sap> is the address that we-re going to listen for
+ // connections on. jwh1: can reuse be used w/ ssl?
+
+ ACE_Secure_SOCK_Acceptor (const ACE_Addr &local_sap,
+ ACE_Protocol_Info *protocolinfo,
+ ACE_SOCK_GROUP g,
+ u_long flags,
+ int reuse_addr,
+ int protocol_family,
+ int backlog = ACE_DEFAULT_BACKLOG,
+ int protocol = 0);
+ // Initialize a passive-mode QoS-enabled acceptor socket. Returns 0
+ // on success and -1 on failure.
+
+ int open (const ACE_Addr &local_sap,
+ int reuse_addr = 0,
+ int protocol_family = PF_INET,
+ int backlog = ACE_DEFAULT_BACKLOG,
+ int protocol = 0);
+ // Initiate a passive mode ssl/BSD-style acceptor socket.
+ // <local_sap> is the address that we-re going to listen for
+ // connections on. jwh1: can reuse be used w/ ssl?
+
+ ~ACE_Secure_SOCK_Acceptor (void);
+ // Default dtor.
+
+ // = Passive connection <accept> methods.
+ int accept (ACE_Secure_SOCK_Stream &new_stream,
+ ACE_Addr *remote_addr = 0,
+ ACE_Time_Value *timeout = 0,
+ int restart = 1,
+ int reset_new_handle = 0) const;
+ // Accept a new <ACE_Secure_SOCK_Stream> connection. A <timeout> of 0
+ // means block forever, a <timeout> of {0, 0} means poll. <restart>
+ // == 1 means "restart if interrupted," i.e., if errno == EINTR.
+
+ int accept (ACE_Secure_SOCK_Stream &new_stream,
+ ACE_Accept_QoS_Params qos_params,
+ ACE_Addr *remote_addr = 0,
+ ACE_Time_Value *timeout = 0,
+ int restart = 1,
+ int reset_new_handle = 0) const;
+ // Accept a new <ACE_Secure_SOCK_Stream> connection using the RVSP QoS
+ // information in <qos_params>. A <timeout> of 0 means block
+ // forever, a <timeout> of {0, 0} means poll. <restart> == 1 means
+ // "restart if interrupted," i.e., if errno == EINTR.
+
+
+ int get_local_addr (ACE_Addr &) const;
+ // Gets the address which is being listened on.
+
+ // = Meta-type info
+ typedef ACE_INET_Addr PEER_ADDR;
+ typedef ACE_Secure_SOCK_Stream PEER_STREAM;
+
+ void dump (void) const;
+ // Dump the state of an object.
+
+ ACE_ALLOC_HOOK_DECLARE;
+ // Declare the dynamic allocation hooks.
+
+protected:
+ int shared_ssl_init_one (ACE_Secure_SOCK_Stream& new_stream) const;
+ // SSL init method which gets called before the socket acceptance.
+
+ int shared_ssl_init_two (ACE_Secure_SOCK_Stream& new_stream) const;
+ // SSL init method which gets calles after the socket acceptance,
+ // SSL_accept is called here.
+
+public:
+ ACE_SOCK_Acceptor acceptor_;
+ // The BSD-socket workhorse
+};
+
+#endif /* ACE_SECURE_SOCK_ACCEPTOR_H */
+#endif /* defined (ACE_HAS_OPENSSL) */
diff --git a/ace/Secure_SOCK_Connector.cpp b/ace/Secure_SOCK_Connector.cpp
new file mode 100644
index 00000000000..126cc2eadc7
--- /dev/null
+++ b/ace/Secure_SOCK_Connector.cpp
@@ -0,0 +1,251 @@
+// Secure_SOCK_Connector.cpp
+// $Id$
+
+#define ACE_HAS_OPENSSL
+#if defined (ACE_HAS_OPENSSL)
+
+#define ACE_BUILD_DLL
+
+#include "Secure_SOCK_Connector.h"
+#include "ace/Handle_Set.h"
+#include "ace/INET_Addr.h"
+#include <openssl/err.h>
+
+#if defined (ACE_LACKS_INLINE_FUNCTIONS)
+#include "ace/Secure_SOCK_Connector.i"
+#endif /* ACE_LACKS_INLINE_FUNCTIONS */
+
+ACE_Secure_SOCK_Connector::ACE_Secure_SOCK_Connector (void)
+{
+ ACE_TRACE ("ACE_Secure_SOCK_Connector::ACE_Secure_SOCK_Connector");
+}
+
+ACE_Secure_SOCK_Connector::~ACE_Secure_SOCK_Connector (void)
+{
+ ACE_TRACE ("ACE_Secure_SOCK_Connector::~ACE_Secure_SOCK_Connector");
+}
+
+int
+ACE_Secure_SOCK_Connector::reset_new_handle (ACE_HANDLE handle)
+{
+ ACE_TRACE ("ACE_Secure_SOCK_Connector::reset_new_handle");
+ connector_.reset_new_handle (handle);
+}
+
+ACE_ALLOC_HOOK_DEFINE(ACE_Secure_SOCK_Connector)
+
+void
+ACE_Secure_SOCK_Connector::dump (void) const
+{
+ ACE_TRACE ("ACE_Secure_SOCK_Connector::dump");
+}
+/*
+int
+ACE_Secure_SOCK_Connector::shared_connect_start (
+ ACE_Secure_SOCK_Stream &new_stream,
+ ACE_Time_Value *timeout,
+ const ACE_Addr &local_sap,
+ int reuse_addr,
+ int protocol_family,
+ int protocol)
+{
+ ACE_TRACE ("ACE_Secure_SOCK_Connector::shared_connect_start");
+ return connector_.shared_connect_start (new_stream.peer (),
+ timeout,
+ local_sap,
+ reuse_addr,
+ protocol_family,
+ protocol);
+}
+
+int
+ACE_Secure_SOCK_Connector::shared_connect_finish (
+ ACE_Secure_SOCK_Stream &new_stream,
+ ACE_Time_Value *timeout,
+ int result)
+{
+ ACE_TRACE ("ACE_Secure_SOCK_Connector::shared_connect_finish");
+ return connector_.shared_connect_finish (new_stream.peer (),
+ timeout,
+ result);
+ // Never add anything else in here, it will be bypassed.
+}
+// Actively connect and produce a new ACE_Secure_SOCK_Stream if things go well...
+*/
+int
+ACE_Secure_SOCK_Connector::connect (ACE_Secure_SOCK_Stream &new_stream,
+ const ACE_Addr &remote_sap,
+ ACE_Time_Value *timeout,
+ const ACE_Addr &local_sap,
+ int reuse_addr,
+ int flags,
+ int perms,
+ int protocol_family,
+ int protocol)
+{
+ ACE_TRACE ("ACE_Secure_SOCK_Connector::connect");
+ if (connector_.connect (new_stream.peer (),
+ remote_sap,
+ timeout,
+ local_sap,
+ reuse_addr,
+ flags,
+ perms,
+ protocol_family,
+ protocol) == -1) {
+ return -1;
+ }
+ return shared_ssl_init (new_stream);
+
+}
+
+int
+ACE_Secure_SOCK_Connector::connect (ACE_Secure_SOCK_Stream &new_stream,
+ const ACE_Addr &remote_sap,
+ ACE_QoS_Params qos_params,
+ ACE_Time_Value *timeout,
+ const ACE_Addr &local_sap,
+ ACE_Protocol_Info *protocolinfo,
+ ACE_SOCK_GROUP g,
+ u_long flags,
+ int reuse_addr,
+ int perms,
+ int protocol_family,
+ int protocol)
+{
+ ACE_TRACE ("ACE_Secure_SOCK_Connector::connect");
+ if (connector_.connect (new_stream.peer (),
+ remote_sap,
+ qos_params,
+ timeout,
+ local_sap,
+ protocolinfo,
+ g,
+ flags,
+ reuse_addr,
+ perms,
+ protocol_family,
+ protocol) == -1) {
+ return -1;
+ }
+ return shared_ssl_init (new_stream);
+}
+
+// Try to complete a non-blocking connection.
+
+int
+ACE_Secure_SOCK_Connector::complete (ACE_Secure_SOCK_Stream &new_stream,
+ ACE_Addr *remote_sap,
+ ACE_Time_Value *tv)
+{
+ ACE_TRACE ("ACE_Secure_SOCK_Connector::complete");
+ if (connector_.complete (new_stream.peer (),
+ remote_sap,
+ tv) == -1) {
+ return -1;
+ }
+ else {
+ //jwh1: Check to see if ssl stuff has completed.
+ }
+ return 0;
+}
+
+ACE_Secure_SOCK_Connector::ACE_Secure_SOCK_Connector (
+ ACE_Secure_SOCK_Stream &new_stream,
+ const ACE_Addr &remote_sap,
+ ACE_Time_Value *timeout,
+ const ACE_Addr &local_sap,
+ int reuse_addr,
+ int flags,
+ int perms,
+ int protocol_family,
+ int protocol)
+{
+ ACE_TRACE ("ACE_Secure_SOCK_Connector::ACE_Secure_SOCK_Connector");
+
+ if (this->connect (new_stream,
+ remote_sap,
+ timeout,
+ local_sap,
+ reuse_addr,
+ flags,
+ perms,
+ protocol_family,
+ protocol) == -1
+ && timeout != 0
+ && !(errno == EWOULDBLOCK || errno == ETIME))
+ ACE_ERROR ((LM_ERROR,
+ ASYS_TEXT ("%p\n"),
+ ASYS_TEXT (
+ "ACE_Secure_SOCK_Connector::ACE_Secure_SOCK_Connector"
+ )));
+
+ shared_ssl_init (new_stream);
+ //jwh1: Wrap this in error catching code
+}
+
+
+
+ACE_Secure_SOCK_Connector::ACE_Secure_SOCK_Connector (
+ ACE_Secure_SOCK_Stream &new_stream,
+ const ACE_Addr &remote_sap,
+ ACE_QoS_Params qos_params,
+ ACE_Time_Value *timeout,
+ const ACE_Addr &local_sap,
+ ACE_Protocol_Info *protocolinfo = 0,
+ ACE_SOCK_GROUP g = 0,
+ u_long flags,
+ int reuse_addr,
+ int perms,
+ int protocol_family,
+ int protocol)
+{
+ ACE_TRACE ("ACE_Secure_SOCK_Connector::ACE_Secure_SOCK_Connector");
+
+ if (this->connect (new_stream,
+ remote_sap,
+ qos_params,
+ timeout,
+ local_sap,
+ protocolinfo,
+ g,
+ flags,
+ reuse_addr,
+ perms,
+ protocol_family,
+ protocol) == -1
+ && timeout != 0
+ && !(errno == EWOULDBLOCK || errno == ETIME))
+ ACE_ERROR ((LM_ERROR,
+ ASYS_TEXT ("%p\n"),
+ ASYS_TEXT (
+ "ACE_Secure_SOCK_Connector::ACE_Secure_SOCK_Connector"
+ )));
+
+ shared_ssl_init (new_stream);
+ //jwh1: Wrap this in error catching code.
+}
+#define CHK_NULL(x) if ((x)==NULL) exit (1)
+#define CHK_ERR(err,s) if ((err)==-1) { perror(s); exit(1); }
+#define CHK_SSL(err) if ((err)==-1) { ERR_print_errors_fp(stderr); exit(2);}
+
+int
+ACE_Secure_SOCK_Connector::shared_ssl_init (ACE_Secure_SOCK_Stream& new_stream)
+{
+
+ SSL_library_init();
+ SSL_METHOD* meth = SSLv2_client_method();
+ SSL_load_error_strings();
+ SSL_CTX* ctx = SSL_CTX_new (meth); CHK_NULL(ctx);
+
+ SSL* ssl = SSL_new (ctx); CHK_NULL(ssl);
+ SSL_set_fd (ssl, new_stream.get_handle ());
+
+ int err = SSL_connect (ssl); CHK_SSL(err);
+
+ new_stream.session (ssl);
+
+ return err;
+}
+
+#endif /* defined (ACE_HAS_OPENSSL) */
diff --git a/ace/Secure_SOCK_Connector.h b/ace/Secure_SOCK_Connector.h
new file mode 100644
index 00000000000..d2126330845
--- /dev/null
+++ b/ace/Secure_SOCK_Connector.h
@@ -0,0 +1,186 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// ace
+//
+// = FILENAME
+// Secure_SOCK_Connector.h
+//
+// = AUTHOR
+// John Heitmann
+//
+// ============================================================================
+
+#define ACE_HAS_OPENSSL
+#if defined (ACE_HAS_OPENSSL)
+
+#ifndef ACE_SECURE_SOCK_CONNECTOR_H
+#define ACE_SECURE_SOCK_CONNECTOR_H
+
+#include "ace/SOCK_Connector.h"
+#include "Secure_SOCK_Stream.h"
+
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+class ACE_Export ACE_Secure_SOCK_Connector
+{
+ // = TITLE
+ // Defines a factory that creates new <ACE_Stream>s actively.
+ //
+ // = DESCRIPTION
+ // The <ACE_SOCK_Connector> doesn't have a socket of its own,
+ // i.e., it simply "borrows" the one from the ACE_SOCK_Stream
+ // that's being connected. The reason for this is that the
+ // underlying socket API doesn't use a "factory" socket to connect
+ // "data-mode" sockets. Therefore, there's no need to inherit
+ // <ACE_SOCK_Connector> from <ACE_SOCK>. A nice side-effect of
+ // this is that <ACE_SOCK_Connector>'s do not store state so they
+ // can be used reentrantly in multi-threaded programs.
+public:
+ // = Initialization and termination methods.
+ ACE_Secure_SOCK_Connector (void);
+ // Default constructor.
+
+ ACE_Secure_SOCK_Connector (ACE_Secure_SOCK_Stream &new_stream,
+ const ACE_Addr &remote_sap,
+ ACE_Time_Value *timeout = 0,
+ const ACE_Addr &local_sap = ACE_Addr::sap_any,
+ int reuse_addr = 0,
+ int flags = 0,
+ int perms = 0,
+ int protocol_family = PF_INET,
+ int protocol = 0);
+ // Actively connect and produce a <new_stream> if things go well.
+ // The <remote_sap> is the address that we are trying to connect
+ // with. The <timeout> is the amount of time to wait to connect.
+ // If it's 0 then we block indefinitely. If *timeout == {0, 0} then
+ // the connection is done using non-blocking mode. In this case, if
+ // the connection can't be made immediately the value of -1 is
+ // returned with <errno == EWOULDBLOCK>. If *timeout > {0, 0} then
+ // this is the amount of time to wait before timing out. If the
+ // time expires before the connection is made <errno == ETIME>. The
+ // <local_sap> is the value of local address to bind to. If it's
+ // the default value of <ACE_Addr::sap_any> then the user is letting
+ // the OS do the binding. If <reuse_addr> == 1 then the
+ // <local_addr> is reused, even if it hasn't been cleanedup yet.
+
+ ACE_Secure_SOCK_Connector (ACE_Secure_SOCK_Stream &new_stream,
+ const ACE_Addr &remote_sap,
+ ACE_QoS_Params qos_params,
+ ACE_Time_Value *timeout = 0,
+ const ACE_Addr &local_sap = ACE_Addr::sap_any,
+ ACE_Protocol_Info *protocolinfo = 0,
+ ACE_SOCK_GROUP g = 0,
+ u_long flags = 0,
+ int reuse_addr = 0,
+ int perms = 0,
+ int protocol_family = PF_INET,
+ int protocol = 0);
+ // Actively connect and produce a <new_stream> if things go well.
+ // The <remote_sap> is the address that we are trying to connect
+ // with. The <qos_params> contains QoS parameters that are passed
+ // to RSVP. The <timeout> is the amount of time to wait to connect.
+ // If it's 0 then we block indefinitely. If *timeout == {0, 0} then
+ // the connection is done using non-blocking mode. In this case, if
+ // the connection can't be made immediately the value of -1 is
+ // returned with <errno == EWOULDBLOCK>. If *timeout > {0, 0} then
+ // this is the amount of time to wait before timing out. If the
+ // time expires before the connection is made <errno == ETIME>. The
+ // <local_sap> is the value of local address to bind to. If it's
+ // the default value of <ACE_Addr::sap_any> then the user is letting
+ // the OS do the binding. If <reuse_addr> == 1 then the
+ // <local_addr> is reused, even if it hasn't been cleanedup yet.
+
+ int connect (ACE_Secure_SOCK_Stream &new_stream,
+ const ACE_Addr &remote_sap,
+ ACE_Time_Value *timeout = 0,
+ const ACE_Addr &local_sap = ACE_Addr::sap_any,
+ int reuse_addr = 0,
+ int flags = 0,
+ int perms = 0,
+ int protocol_family = PF_INET,
+ int protocol = 0);
+ // Actively connect and produce a <new_stream> if things go well.
+ // The <remote_sap> is the address that we are trying to connect
+ // with. The <timeout> is the amount of time to wait to connect.
+ // If it's 0 then we block indefinitely. If *timeout == {0, 0} then
+ // the connection is done using non-blocking mode. In this case, if
+ // the connection can't be made immediately the value of -1 is
+ // returned with <errno == EWOULDBLOCK>. If *timeout > {0, 0} then
+ // this is the amount of time to wait before timing out. If the
+ // time expires before the connection is made <errno == ETIME>. The
+ // <local_sap> is the value of local address to bind to. If it's
+ // the default value of <ACE_Addr::sap_any> then the user is letting
+ // the OS do the binding. If <reuse_addr> == 1 then the
+ // <local_addr> is reused, even if it hasn't been cleanedup yet.
+
+ int connect (ACE_Secure_SOCK_Stream &new_stream,
+ const ACE_Addr &remote_sap,
+ ACE_QoS_Params qos_params,
+ ACE_Time_Value *timeout = 0,
+ const ACE_Addr &local_sap = ACE_Addr::sap_any,
+ ACE_Protocol_Info *protocolinfo = 0,
+ ACE_SOCK_GROUP g = 0,
+ u_long flags = 0,
+ int reuse_addr = 0,
+ int perms = 0,
+ int protocol_family = PF_INET,
+ int protocol = 0);
+ // Actively connect and produce a <new_stream> if things go well.
+ // The <remote_sap> is the address that we are trying to connect
+ // with. The <qos_params> contains QoS parameters that are passed
+ // to RSVP. The <timeout> is the amount of time to wait to connect.
+ // If it's 0 then we block indefinitely. If *timeout == {0, 0} then
+ // the connection is done using non-blocking mode. In this case, if
+ // the connection can't be made immediately the value of -1 is
+ // returned with <errno == EWOULDBLOCK>. If *timeout > {0, 0} then
+ // this is the amount of time to wait before timing out. If the
+ // time expires before the connection is made <errno == ETIME>. The
+ // <local_sap> is the value of local address to bind to. If it's
+ // the default value of <ACE_Addr::sap_any> then the user is letting
+ // the OS do the binding. If <reuse_addr> == 1 then the
+ // <local_addr> is reused, even if it hasn't been cleanedup yet.
+
+ ~ACE_Secure_SOCK_Connector (void);
+ // Default dtor.
+
+ // = Completion routine.
+ int complete (ACE_Secure_SOCK_Stream &new_stream,
+ ACE_Addr *remote_sap = 0,
+ ACE_Time_Value *timeout = 0);
+ // Try to complete a non-blocking connection.
+ // If connection completion is successful then <new_stream> contains
+ // the connected ACE_SOCK_Stream. If <remote_sap> is non-NULL then it
+ // will contain the address of the connected peer.
+
+ int reset_new_handle (ACE_HANDLE handle);
+ // Resets any event associations on this handle
+
+ // = Meta-type info
+ typedef ACE_INET_Addr PEER_ADDR;
+ typedef ACE_Secure_SOCK_Stream PEER_STREAM;
+
+ void dump (void) const;
+ // Dump the state of an object.
+
+ ACE_ALLOC_HOOK_DECLARE;
+ // Declare the dynamic allocation hooks.
+protected:
+ // Perform operations that must be called after <ACE_OS::connect>.
+
+ int shared_ssl_init (ACE_Secure_SOCK_Stream& new_stream);
+
+private:
+ ACE_SOCK_Connector connector_;
+ // The class that does all of the non-secure socket connection.
+ // It is default contructed, and susequently used by connect().
+};
+
+#endif /* ACE_SECURE_SOCK_CONNECTOR_H */
+#endif /* defined (ACE_HAS_OPENSSL) */
diff --git a/ace/Secure_SOCK_Stream.cpp b/ace/Secure_SOCK_Stream.cpp
new file mode 100644
index 00000000000..ec959ae6478
--- /dev/null
+++ b/ace/Secure_SOCK_Stream.cpp
@@ -0,0 +1,777 @@
+// Secure_SOCK_Stream.cpp
+// $Id$
+#define ACE_HAS_OPENSSL
+#if defined (ACE_HAS_OPENSSL)
+
+#define ACE_BUILD_DLL
+#include "Secure_SOCK_Stream.h"
+#include <ace/Handle_Set.h>
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+
+#if defined (ACE_LACKS_INLINE_FUNCTIONS)
+#include "Secure_SOCK_Stream.i"
+#endif
+
+ACE_ALLOC_HOOK_DEFINE(ACE_Secure_SOCK_Stream)
+
+ACE_Secure_SOCK_Stream::ACE_Secure_SOCK_Stream (void)
+{
+ ACE_TRACE ("ACE_Secure_SOCK_Stream::ACE_Secure_SOCK_Stream");
+}
+
+ACE_Secure_SOCK_Stream::ACE_Secure_SOCK_Stream (ACE_HANDLE h)
+ : stream_ (h)
+{
+ ACE_TRACE ("ACE_Secure_SOCK_Stream::ACE_Secure_SOCK_Stream");
+}
+
+ACE_Secure_SOCK_Stream::~ACE_Secure_SOCK_Stream (void)
+{
+ ACE_TRACE ("ACE_Secure_SOCK_Stream::~ACE_Secure_SOCK_Stream");
+}
+
+ssize_t
+ACE_Secure_SOCK_Stream::send (const void *buf,
+ size_t n,
+ int flags) const
+{
+ ACE_TRACE ("ACE_Secure_SOCK_Stream::send");
+ // No send flags are supported in SSL.
+ if (flags != 0)
+ {
+ ACE_NOTSUP_RETURN (-1);
+ }
+ else
+ return SSL_write (ssl_, ACE_static_cast (const char*, buf), n);
+}
+
+ssize_t
+ACE_Secure_SOCK_Stream::recv (void *buf,
+ size_t n,
+ int flags) const
+{
+ ACE_TRACE ("ACE_Secure_SOCK_Stream::recv");
+ if (flags != 0)
+ {
+ if ((flags | MSG_PEEK) == MSG_PEEK)
+ return SSL_peek (ssl_, ACE_static_cast (char*, buf), n);
+ else
+ ACE_NOTSUP_RETURN (-1);
+ }
+ return SSL_read (ssl_, ACE_static_cast (char*, buf), n);
+}
+
+ssize_t
+ACE_Secure_SOCK_Stream::send (const void *buf,
+ size_t n) const
+{
+ ACE_TRACE ("ACE_Secure_SOCK_Stream::send");
+ return SSL_write (ssl_, ACE_static_cast (const char*, buf), n);
+}
+
+ssize_t
+ACE_Secure_SOCK_Stream::recv (void *buf,
+ size_t n) const
+{
+ ACE_TRACE ("ACE_Secure_SOCK_Stream::recv");
+ return SSL_read (ssl_, ACE_static_cast (char*, buf), n);
+}
+
+ssize_t
+ACE_Secure_SOCK_Stream::sendv (const iovec iov[],
+ size_t n) const
+{
+ ACE_TRACE ("ACE_Secure_SOCK_Stream::sendv");
+
+ // Mimics ACE_OS::sendv.
+ int result = 0;
+ ssize_t bytes_sent = 0;
+ for (size_t i = 0; i < n && result != -1; i++)
+ {
+ result = this->send (iov[i].iov_base,
+ iov[i].iov_len);
+ bytes_sent += iov[i].iov_len; // Gets ignored on error anyway
+ }
+
+ if (result == -1)
+ return -1;
+ else
+ return bytes_sent;
+}
+
+ssize_t
+ACE_Secure_SOCK_Stream::send (const iovec iov[],
+ size_t n) const
+{
+ ACE_TRACE ("ACE_Secure_SOCK_Stream::send");
+ return this->sendv (iov, n);
+}
+
+ssize_t
+ACE_Secure_SOCK_Stream::recvv (iovec *io_vec,
+ const ACE_Time_Value *timeout = 0) const
+{
+ ACE_TRACE ("ACE_Secure_SOCK_Stream::recvv");
+
+ // From <ACE_SOCK_IO::recvv>.
+#if defined (FIONREAD)
+ ACE_Handle_Set handle_set;
+ handle_set.reset ();
+ handle_set.set_bit (this->get_handle ());
+
+ io_vec->iov_base = 0;
+
+ // Check the status of the current socket.
+ switch (ACE_OS::select (int (this->get_handle ()) + 1,
+ handle_set,
+ 0, 0,
+ timeout))
+ {
+ case -1:
+ return -1;
+ /* NOTREACHED */
+ case 0:
+ errno = ETIME;
+ return -1;
+ /* NOTREACHED */
+ default:
+ // Goes fine, fallthrough to get data
+ break;
+ }
+
+ u_long inlen;
+
+ if (ACE_OS::ioctl (this->get_handle (),
+ FIONREAD,
+ (u_long *) &inlen) == -1)
+ return -1;
+ else if (inlen > 0)
+ {
+ ACE_NEW_RETURN (io_vec->iov_base,
+ char[inlen],
+ -1);
+ io_vec->iov_len = this->recv (io_vec->iov_base,
+ inlen);
+ return io_vec->iov_len;
+ }
+ else
+ return 0;
+#else
+ ACE_UNUSED_ARG (io_vec);
+ ACE_UNUSED_ARG (timeout);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* FIONREAD */
+}
+
+ssize_t
+ACE_Secure_SOCK_Stream::recv (iovec *io_vec,
+ const ACE_Time_Value *timeout = 0) const
+{
+ ACE_TRACE ("ACE_Secure_SOCK_Stream::recv");
+ return this->recvv (io_vec, timeout);
+}
+
+ssize_t
+ACE_Secure_SOCK_Stream::send (const void *buf,
+ size_t len,
+ int flags,
+ const ACE_Time_Value *timeout) const
+{
+ ACE_TRACE ("ACE_Secure_SOCK_Stream::send");
+ if (flags !=0)
+ {
+ ACE_NOTSUP_RETURN (-1);
+ }
+ // Mimics <ACE::send>.
+ if (timeout == 0)
+ return this->send (buf, len);
+
+ int val;
+ if (this->enter_send_timedwait (timeout, val) == -1)
+ return -1;
+ ssize_t bytes_written = this->send (buf, len);
+ this->leave_send_timedwait (timeout, val);
+ return bytes_written;
+}
+
+ssize_t
+ACE_Secure_SOCK_Stream::recv (void *buf,
+ size_t n,
+ int flags,
+ const ACE_Time_Value *timeout) const
+{
+ ACE_TRACE ("ACE_Secure_SOCK_Stream::recv");
+ // Mimics code in <ACE::recv>.
+ int peek;
+ if (flags != 0)
+ {
+ if ((flags | MSG_PEEK) == MSG_PEEK)
+ peek = 1;
+ else
+ ACE_NOTSUP_RETURN (-1);
+ }
+ if (timeout == 0)
+ return this->recv (buf, n, flags);
+ int val = 0;
+ if (this->enter_recv_timedwait (timeout, val) == -1)
+ return -1;
+ ssize_t bytes_recv = this->recv (buf, n, flags);
+ this->leave_recv_timedwait (timeout, val);
+ return bytes_recv;
+}
+
+ssize_t
+ACE_Secure_SOCK_Stream::send (const void *buf,
+ size_t len,
+ const ACE_Time_Value *timeout) const
+{
+ ACE_TRACE ("ACE_Secure_SOCK_Stream::send");
+ return this->send (buf, len, 0, timeout);
+}
+
+ssize_t
+ACE_Secure_SOCK_Stream::recv (void *buf,
+ size_t n,
+ const ACE_Time_Value *timeout) const
+{
+ ACE_TRACE ("ACE_Secure_SOCK_Stream::recv");
+ return this->recv (buf, n, 0, timeout);
+}
+
+ssize_t
+ACE_Secure_SOCK_Stream::send (size_t n,
+ ...) const
+{
+ ACE_TRACE ("ACE_Secure_SOCK_Stream::send");
+
+ // Mimics <ACE_SOCK_IO::send (...)>.
+ va_list argp;
+ size_t total_tuples = n / 2;
+ iovec *iovp;
+#if defined (ACE_HAS_ALLOCA)
+ iovp = (iovec *) alloca (total_tuples * sizeof (iovec));
+#else
+ ACE_NEW_RETURN (iovp,
+ iovec[total_tuples],
+ -1);
+#endif /* !defined (ACE_HAS_ALLOCA) */
+
+ va_start (argp, n);
+
+ for (size_t i = 0; i < total_tuples; i++)
+ {
+ iovp[i].iov_base = va_arg (argp, char *);
+ iovp[i].iov_len = va_arg (argp, ssize_t);
+ }
+
+ ssize_t result = this->sendv (iovp,
+ total_tuples);
+#if !defined (ACE_HAS_ALLOCA)
+ delete [] iovp;
+#endif /* !defined (ACE_HAS_ALLOCA) */
+ va_end (argp);
+ return result;
+}
+
+ssize_t
+ACE_Secure_SOCK_Stream::recv (size_t n,
+ ...) const
+{
+ ACE_TRACE ("ACE_Secure_SOCK_Stream::recv");
+ va_list argp;
+ size_t total_tuples = n / 2;
+ iovec *iovp;
+#if defined (ACE_HAS_ALLOCA)
+ iovp = (iovec *) alloca (total_tuples * sizeof (iovec));
+#else
+ ACE_NEW_RETURN (iovp,
+ iovec[total_tuples],
+ -1);
+#endif /* !defined (ACE_HAS_ALLOCA) */
+
+ va_start (argp, n);
+
+ for (size_t i = 0; i < total_tuples; i++)
+ {
+ iovp[i].iov_base = va_arg (argp, char *);
+ iovp[i].iov_len = va_arg (argp, ssize_t);
+ }
+
+ ssize_t result = this->recvv (iovp,0);
+#if !defined (ACE_HAS_ALLOCA)
+ delete [] iovp;
+#endif /* !defined (ACE_HAS_ALLOCA) */
+ va_end (argp);
+ return result;
+}
+
+ssize_t
+ACE_Secure_SOCK_Stream::send_n (const void *buf, size_t len, int flags,
+ const ACE_Time_Value *timeout) const
+{
+ ACE_TRACE ("ACE_Secure_SOCK_Stream::send_n");
+
+ //no support for send flags in SSL
+ if (flags != 0)
+ ACE_NOTSUP_RETURN (-1);
+
+ /* This code mimics ACE::send_n */
+ // Total number of bytes written.
+ size_t bytes_written;
+
+ // Actual number of bytes written in each <send> attempt
+ ssize_t n;
+
+ for (bytes_written = 0;
+ bytes_written < len;
+ bytes_written += n)
+ {
+ n = this->send ((const char*) buf + bytes_written,
+ len - bytes_written,
+ flags,
+ timeout);
+ if (n == -1)
+ if (errno == EWOULDBLOCK)
+ n = 0; // Keep trying to send
+ else
+ return -1;
+ }
+ return bytes_written;
+}
+
+ssize_t
+ACE_Secure_SOCK_Stream::recv_n (void *buf, size_t len, int flags,
+ const ACE_Time_Value *timeout) const
+{
+ ACE_TRACE ("ACE_Secure_SOCK_Stream::recv_n");
+ if (flags != 0)
+ {
+ if ((flags | MSG_PEEK) != MSG_PEEK)
+ ACE_NOTSUP_RETURN (-1);
+ }
+ size_t bytes_received;
+
+ ssize_t n;
+
+ for (bytes_received = 0;
+ bytes_received < len;
+ bytes_received += n)
+ {
+ n = this->recv ((char*) buf + bytes_received,
+ len - bytes_received,
+ flags,
+ timeout);
+ if (n == -1 || n == 0)
+ break;
+ }
+
+ return bytes_received;
+}
+
+ssize_t
+ACE_Secure_SOCK_Stream::recv_n (void *buf, int len, int flags) const
+{
+ ACE_TRACE ("ACE_Secure_SOCK_Stream::recv_n");
+ if (flags != 0)
+ {
+ if ((flags | MSG_PEEK) != MSG_PEEK)
+ ACE_NOTSUP_RETURN (-1);
+ }
+ ssize_t bytes_received;
+
+ ssize_t n;
+
+ for (bytes_received = 0;
+ bytes_received < len;
+ bytes_received += n)
+ {
+ n = this->recv ((char*) buf + bytes_received,
+ len - bytes_received,
+ flags);
+ if (n == -1)
+ {
+ if (errno == EWOULDBLOCK)
+ n = 0; //Keep trying
+ else
+ return -1;
+ }
+ else if (n == 0)
+ break;
+ }
+
+ return bytes_received;
+}
+
+ssize_t
+ACE_Secure_SOCK_Stream::send_n (const void *buf, int len, int flags) const
+{
+ ACE_TRACE ("ACE_Secure_SOCK_Stream::send_n");
+
+ // Send flags are unsupported in SSL
+ if (flags != 0)
+ ACE_NOTSUP_RETURN (-1);
+
+ /* The following code mimics <ACE::send_n> */
+ size_t bytes_written;
+ ssize_t n;
+
+ for (bytes_written = 0;
+ bytes_written < (size_t) len;
+ bytes_written += n)
+ {
+ n = this->send ((const char*) buf + bytes_written,
+ len - bytes_written,
+ flags);
+ if (n == -1)
+ {
+ if (errno == EWOULDBLOCK)
+ n = 0; //Keep trying to send.
+ else
+ return -1;
+ }
+ }
+ return bytes_written;
+}
+
+ssize_t
+ACE_Secure_SOCK_Stream::recv_n (void *buf, int buf_size) const
+{
+ ACE_TRACE ("ACE_Secure_SOCK_Stream::recv_n");
+ return this->recv_n (buf, buf_size, 0);
+}
+
+//jwh1: default this?
+ssize_t
+ACE_Secure_SOCK_Stream::send_n (const void *buf, int len) const
+{
+ ACE_TRACE ("ACE_Secure_SOCK_Stream::send_n");
+ return this->send_n (buf, len, 0);
+}
+
+//Taken from OS.cpp, writev ()
+ssize_t
+ACE_Secure_SOCK_Stream::sendv_n (const iovec iov[], size_t n) const
+{
+ ACE_TRACE ("ACE_Secure_SOCK_Stream::sendv_n");
+ size_t length = 0;
+ size_t i;
+
+ // Determine the total length of all the buffers in <iov>.
+ for (i = 0; i < n; i++)
+ if (ACE_static_cast (int, iov[i].iov_len) < 0)
+ return -1;
+ else
+ length += iov[i].iov_len;
+
+ char *buf;
+
+# if defined (ACE_HAS_ALLOCA)
+ buf = (char *) alloca (length);
+# else
+ ACE_NEW_RETURN (buf,
+ char[length],
+ -1);
+# endif /* !defined (ACE_HAS_ALLOCA) */
+
+ char *ptr = buf;
+
+ for (i = 0; i < n; i++)
+ {
+ ACE_OS::memcpy (ptr, iov[i].iov_base, iov[i].iov_len);
+ ptr += iov[i].iov_len;
+ }
+
+ ssize_t result = this->send_n (buf, length);
+# if !defined (ACE_HAS_ALLOCA)
+ delete [] buf;
+# endif /* !defined (ACE_HAS_ALLOCA) */
+ return result;
+}
+
+// Taken straight from OS.cpp, readv ()
+ssize_t
+ACE_Secure_SOCK_Stream::recvv_n (iovec iov[], size_t n) const
+{
+ ACE_TRACE ("ACE_Secure_SOCK_Stream::recvv_n");
+ ssize_t length = 0;
+ size_t i;
+
+ for (i = 0; i < n; i++)
+ if (ACE_static_cast (int, iov[i].iov_len) < 0)
+ return -1;
+ else
+ length += iov[i].iov_len;
+
+ char *buf;
+# if defined (ACE_HAS_ALLOCA)
+ buf = (char *) alloca (length);
+# else
+ ACE_NEW_RETURN (buf,
+ char[length],
+ -1);
+# endif /* !defined (ACE_HAS_ALLOCA) */
+
+ length = this->recv_n (buf, length);
+
+ if (length != -1)
+ {
+ char *ptr = buf;
+ int copyn = length;
+
+ for (i = 0;
+ i < n && copyn > 0;
+ i++)
+ {
+ ACE_OS::memcpy (iov[i].iov_base, ptr,
+ // iov_len is int on some platforms, size_t on others
+ copyn > (int) iov[i].iov_len
+ ? (size_t) iov[i].iov_len
+ : (size_t) copyn);
+ ptr += iov[i].iov_len;
+ copyn -= iov[i].iov_len;
+ }
+ }
+
+# if !defined (ACE_HAS_ALLOCA)
+ delete [] buf;
+# endif /* !defined (ACE_HAS_ALLOCA) */
+ return length;
+}
+
+int
+ACE_Secure_SOCK_Stream::close_reader (void)
+{
+ ACE_TRACE ("ACE_Secure_SOCK_Stream::close_reader");
+ return stream_.close_reader ();
+}
+
+int
+ACE_Secure_SOCK_Stream::close_writer (void)
+{
+ ACE_TRACE ("ACE_Secure_SOCK_Stream::close_writer");
+ return stream_.close_writer ();
+}
+
+int
+ACE_Secure_SOCK_Stream::close (void)
+{
+ ACE_TRACE ("ACE_Secure_SOCK_Stream::close");
+ SSL_free (ssl_);
+ return stream_.close ();
+}
+
+void
+ACE_Secure_SOCK_Stream::dump (void) const
+{
+ ACE_TRACE ("ACE_Secure_SOCK_Stream::dump");
+ stream_.dump ();
+}
+
+ACE_SOCK_Stream&
+ACE_Secure_SOCK_Stream::peer () {
+ return stream_;
+}
+
+int
+ACE_Secure_SOCK_Stream::set_option (int level,
+ int option,
+ void *optval,
+ int optlen) const
+{
+ ACE_TRACE ("ACE_Secure_SOCK_Stream::set_option");
+ return stream_.set_option (level, option, optval, optlen);
+}
+
+int
+ACE_Secure_SOCK_Stream::get_option (int level,
+ int option,
+ void *optval,
+ int *optlen) const
+{
+ ACE_TRACE ("ACE_Secure_SOCK_Stream::get_option");
+ return stream_.get_option (level, option, optval, optlen);
+}
+
+int
+ACE_Secure_SOCK_Stream::get_local_addr (ACE_Addr &addr) const
+{
+ ACE_TRACE ("ACE_Secure_SOCK_Stream::get_local_addr");
+ return stream_.get_local_addr (addr);
+}
+
+int
+ACE_Secure_SOCK_Stream::get_remote_addr (ACE_Addr &addr) const
+{
+ ACE_TRACE ("ACE_Secure_SOCK_Stream::get_remote_addr");
+ return stream_.get_remote_addr (addr);
+}
+
+void
+ACE_Secure_SOCK_Stream::session (SSL* ssl) {
+ ssl_ = ssl;
+}
+SSL*
+ACE_Secure_SOCK_Stream::session () const {
+ return ssl_;
+}
+
+ACE_HANDLE
+ACE_Secure_SOCK_Stream::get_handle (void) const
+{
+ return stream_.get_handle ();
+}
+
+void
+ACE_Secure_SOCK_Stream::set_handle (ACE_HANDLE handle)
+{
+ stream_.set_handle (handle);
+}
+
+
+// The following four functions are copied straight from ACE::, I may
+// specialize them, or make this class a friend of ACE instead.
+int
+ACE_Secure_SOCK_Stream::enter_recv_timedwait (const ACE_Time_Value *timeout,
+ int &val) const
+{
+ // Give value a default value to keep Purify happy!
+ val = 0;
+ ACE_HANDLE handle = this->get_handle ();
+#if defined (ACE_HAS_POLL) && defined (ACE_HAS_LIMITED_SELECT)
+
+ struct pollfd fds;
+
+ fds.fd = handle;
+ fds.events = POLLIN;
+ fds.revents = 0;
+
+ int a = ACE_OS::poll (&fds, 1, *timeout);
+
+#else
+ ACE_Handle_Set handle_set;
+ handle_set.set_bit (handle);
+
+ // Wait for input to arrive or for the timeout to elapse.
+ int a = ACE_OS::select (int (handle) + 1,
+ (fd_set *) handle_set, // read_fds.
+ (fd_set *) 0, // write_fds.
+ (fd_set *) 0, // exception_fds.
+ timeout);
+#endif /* ACE_HAS_POLL && ACE_HAS_LIMITED_SELECT */
+
+ switch ( a )
+ {
+ case 0: // Timer expired. return -1
+ errno = ETIME;
+ /* FALLTHRU */
+ case -1: // we got here directly - select() returned -1.
+ return -1;
+ case 1: // OK to read now.
+ /* FALLTHRU */
+ default: // default is case a > 0; return a
+ // really should assert if a != 1
+ //assert( a == 1 );
+ // We need to record whether we are already *in* nonblocking
+ // mode, so that we can correctly reset the state when we're
+ // done.
+ val = ACE::get_flags (handle);
+
+ if (ACE_BIT_DISABLED (val, ACE_NONBLOCK))
+ // Set the handle into non-blocking mode if it's not
+ // already in it.
+ ACE::set_flags (handle, ACE_NONBLOCK);
+ return a;
+ }
+}
+
+void
+ACE_Secure_SOCK_Stream::leave_recv_timedwait (const ACE_Time_Value *timeout,
+ int val) const
+{
+ if (timeout != 0
+ && ACE_BIT_DISABLED (val,
+ ACE_NONBLOCK))
+ {
+ // Save/restore errno.
+ ACE_Errno_Guard error (errno);
+ // Only disable ACE_NONBLOCK if we weren't in non-blocking mode
+ // originally.
+ ACE::clr_flags (this->get_handle (), ACE_NONBLOCK);
+ }
+}
+
+int
+ACE_Secure_SOCK_Stream::enter_send_timedwait (const ACE_Time_Value* timeout,
+ int &val) const
+{
+ // Give value a default value to keep Purify happy!
+ val = 0;
+ ACE_HANDLE handle = this->get_handle ();
+#if defined (ACE_HAS_POLL) && defined (ACE_HAS_LIMITED_SELECT)
+
+ struct pollfd fds;
+
+ fds.fd = handle;
+ fds.events = POLLOUT;
+ fds.revents = 0;
+
+ int a = ACE_OS::poll (&fds, 1, *timeout);
+
+#else
+ ACE_Handle_Set handle_set;
+ handle_set.set_bit (handle);
+
+ // On timed writes we always go into select(); only if the
+ // handle is available for writing within the specified amount
+ // of time do we put it in non-blocking mode
+
+ int a = ACE_OS::select (int (handle) + 1,
+ (fd_set *) 0,
+ (fd_set *) handle_set,
+ (fd_set *) 0,
+ timeout);
+#endif /* ACE_HAS_POLL && ACE_HAS_LIMITED_SELECT */
+
+ switch ( a )
+ {
+ case 0: // Timer expired.
+ errno = ETIME;
+ /* FALLTHRU */
+ case -1: // we got here directly - select() returned -1.
+ return -1;
+ case 1: // Ok to write now.
+ /* FALLTHRU */
+ default: // default is case a > 0; return a
+ // really should assert if a != 1
+ //assert( a == 1 );
+ // We need to record whether we are already *in* nonblocking
+ // mode, so that we can correctly reset the state when we're
+ // done.
+ val = ACE::get_flags (handle);
+
+ if (ACE_BIT_DISABLED (val, ACE_NONBLOCK))
+ // Set the handle into non-blocking mode if it's not
+ // already in it.
+ ACE::set_flags (handle, ACE_NONBLOCK);
+ return a;
+ }
+}
+
+void
+ACE_Secure_SOCK_Stream::leave_send_timedwait (const ACE_Time_Value *timeout,
+ int val) const
+{
+ if (timeout != 0
+ && ACE_BIT_DISABLED (val, ACE_NONBLOCK))
+ {
+ // Save/restore errno.
+ ACE_Errno_Guard error (errno);
+ // Only disable ACE_NONBLOCK if we weren't in non-blocking mode
+ // originally.
+ ACE::clr_flags (this->get_handle (), ACE_NONBLOCK);
+ }
+}
+
+
+#endif /* defined (ACE_HAS_OPENSSL) */
diff --git a/ace/Secure_SOCK_Stream.h b/ace/Secure_SOCK_Stream.h
new file mode 100644
index 00000000000..b0b80a9e0f0
--- /dev/null
+++ b/ace/Secure_SOCK_Stream.h
@@ -0,0 +1,204 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// ace
+//
+// = FILENAME
+// Secure_SOCK_Stream.h
+//
+// = AUTHOR
+// John Heitmann
+//
+// ============================================================================
+#define ACE_HAS_OPENSSL
+#if defined (ACE_HAS_OPENSSL)
+
+#ifndef ACE_Secure_SOCK_STREAM_H
+#define ACE_Secure_SOCK_STREAM_H
+#include "ace/SOCK_Stream.h"
+#include <openssl/ssl.h>
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+class ACE_Export ACE_Secure_SOCK_Stream
+{
+ // = TITLE
+ // Defines methods in the <ACE_Secure_SOCK_Stream> abstraction.
+ //
+ // = DESCRIPTION
+ // This adds ssl functionality to an <ACE_SOCK_IO> interface by
+ // wrapping around an <ACE_Secure_SOCK_Stream> implementation.
+ //
+public:
+ // = Initializtion and termination functions.
+ ACE_Secure_SOCK_Stream (void);
+ // Constructor
+
+ ACE_Secure_SOCK_Stream (ACE_HANDLE h);
+ // Constructor (sets the underlying <ACE_HANDLE> with <H>)
+
+ ~ACE_Secure_SOCK_Stream (void);
+ //Destructor
+
+ ssize_t send (const void *buf,
+ size_t n,
+ int flags) const;
+
+ ssize_t recv (void *buf,
+ size_t n,
+ int flags) const;
+
+ ssize_t send (const void *buf,
+ size_t n) const;
+
+ ssize_t recv (void *buf,
+ size_t n) const;
+
+ ssize_t sendv (const iovec iov[],
+ size_t n) const;
+
+ ssize_t send (const iovec iov[],
+ size_t n) const;
+
+ ssize_t recvv (iovec *io_vec,
+ const ACE_Time_Value *timeout = 0) const;
+
+ ssize_t recv (iovec *io_vec,
+ const ACE_Time_Value *timeout = 0) const;
+
+ ssize_t send (const void *buf,
+ size_t n,
+ int flags,
+ const ACE_Time_Value *timeout) const;
+
+ ssize_t recv (void *buf,
+ size_t n,
+ int flags,
+ const ACE_Time_Value *timeout) const;
+
+ ssize_t send (const void *buf,
+ size_t n,
+ const ACE_Time_Value *timeout) const;
+
+ ssize_t recv (void *buf,
+ size_t n,
+ const ACE_Time_Value *timeout) const;
+
+ ssize_t send (size_t n,
+ ...) const;
+ // Send <n> varargs messages to the connected socket.
+
+ ssize_t recv (size_t n,
+ ...) const;
+ // Recv <n> varargs messages to the connected socket.
+
+ // = The following methods all use <SSL_read (SSL*, char*)>
+ // and <SSL_write (SSL*, char*)>
+ ssize_t send_n (const void *buf, int n) const;
+ // Send n bytes, with blocking.
+
+ ssize_t recv_n (void *buf, int n) const;
+ // Recv n bytes, with blocking.
+
+ ssize_t send_n (const void *buf, int n, int flags) const;
+ // Send n bytes, with blocking.
+
+ ssize_t recv_n (void *buf, int n, int flags) const;
+ // Recv n bytes, with blocking.
+
+ ssize_t send_n (const void *buf,
+ size_t len,
+ int flags,
+ const ACE_Time_Value *timeout) const;
+ // Try to send n bytes,
+ // jwh1: figure out timeout semantics.
+
+ ssize_t recv_n (void *buf,
+ size_t len,
+ int flags,
+ const ACE_Time_Value *timeout) const;
+ // Try to send n bytes.
+ // jwh1: figure out timeout semantics.
+
+ ssize_t sendv_n (const iovec iov[],
+ size_t n) const;
+ // Send an <iovec> of size <n>, will block until finished.
+
+ ssize_t recvv_n (iovec iov[],
+ size_t n) const;
+ // Recv an <iovec> of size <n>, will block until finished.
+
+
+ // = Selectively close endpoints.
+ int close_reader (void);
+ // Close down the reader.
+ // jwh1: is this undefined with ssl?
+
+ int close_writer (void);
+ // Close down the writer.
+ // jwh1: is this undefined with ssl?
+
+ int close (void);
+ //Close down the socket and jwh1: ? free the SSL session.
+
+ // = Meta-type info
+ typedef ACE_INET_Addr PEER_ADDR;
+
+ void dump (void) const;
+ // Dump the state of an object.
+
+ ACE_ALLOC_HOOK_DECLARE;
+ // Declare the dynamic allocation hooks.
+
+ // = Accessor methods
+ //jwh1: Make me private.
+ ACE_SOCK_Stream& peer ();
+ // Return the underlying <ACE_SOCK_Stream> which ssl runs on top of.
+
+ int set_option (int level,
+ int option,
+ void *optval,
+ int optlen) const;
+ // Wrapper around the setsockopt() system call.
+
+ int get_option (int level,
+ int option,
+ void *optval,
+ int *optlen) const;
+ // Wrapper around the getsockopt() system call.
+
+ int get_local_addr (ACE_Addr &) const;
+ // Return the local endpoint address in the referenced <ACE_Addr>.
+
+ int get_remote_addr (ACE_Addr &) const;
+ // Return the address of the remotely connected peer (if there is
+ // one), in the referenced ACE_Addr. Returns 0 if successful, else -1.
+
+ // = Accessors for the SSL* session
+ void session (SSL*);
+ SSL* session () const;
+
+ ACE_HANDLE get_handle (void) const;
+ // Get the underlying handle
+
+ void set_handle (ACE_HANDLE handle);
+ // Set the underlying handle
+private:
+ int enter_recv_timedwait (const ACE_Time_Value* timeout, int& val) const;
+ void leave_recv_timedwait (const ACE_Time_Value* timeout, int val) const;
+ int enter_send_timedwait (const ACE_Time_Value* timeout, int& val) const;
+ void leave_send_timedwait (const ACE_Time_Value* timeout, int val) const;
+
+ ACE_SOCK_Stream stream_;
+ // The stream which works under the ssl connection.
+ SSL* ssl_;
+ // The ssl data structure itself.
+};
+
+#endif /* ACE_SECURE_SOCK_STREAM_H */
+#endif /* defined (ACE_HAS_OPENSSL) */