Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
A
Actor Framework
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
cpp-libs
Actor Framework
Commits
1e81bfb5
Commit
1e81bfb5
authored
Apr 26, 2017
by
Robin Sommer
Committed by
Dominik Charousset
Jul 13, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Adressing PR feedback.
parent
1135449e
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
81 additions
and
117 deletions
+81
-117
libcaf_openssl/CMakeLists.txt
libcaf_openssl/CMakeLists.txt
+1
-1
libcaf_openssl/caf/openssl/session.hpp
libcaf_openssl/caf/openssl/session.hpp
+11
-10
libcaf_openssl/src/manager.cpp
libcaf_openssl/src/manager.cpp
+5
-8
libcaf_openssl/src/middleman_actor.cpp
libcaf_openssl/src/middleman_actor.cpp
+21
-33
libcaf_openssl/src/session.cpp
libcaf_openssl/src/session.cpp
+43
-65
No files found.
libcaf_openssl/CMakeLists.txt
View file @
1e81bfb5
...
...
@@ -11,7 +11,7 @@ set (LIBCAF_OPENSSL_SRCS
src/middleman_actor.cpp
src/publish.cpp
src/remote_actor.cpp
src/s
sl_s
ession.cpp
)
src/session.cpp
)
add_custom_target
(
libcaf_openssl
)
...
...
libcaf_openssl/caf/openssl/s
sl_s
ession.hpp
→
libcaf_openssl/caf/openssl/session.hpp
View file @
1e81bfb5
...
...
@@ -17,24 +17,24 @@
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#ifndef CAF_OPENSSL_S
SL_S
ESSION_HPP
#define CAF_OPENSSL_S
SL_S
ESSION_HPP
#ifndef CAF_OPENSSL_SESSION_HPP
#define CAF_OPENSSL_SESSION_HPP
#include "caf/actor_system.hpp"
#include "caf/io/network/native_socket.hpp"
#include <openssl/err.h>
#include <openssl/ssl.h>
namespace
caf
{
namespace
openssl
{
using
native_socket
=
io
::
network
::
native_socket
;
class
s
sl_session
{
class
s
ession
:
public
ref_counted
{
public:
s
sl_s
ession
(
actor_system
&
sys
);
~
s
sl_s
ession
();
session
(
actor_system
&
sys
);
~
session
();
void
init
();
bool
read_some
(
size_t
&
result
,
native_socket
fd
,
void
*
buf
,
size_t
len
);
bool
write_some
(
size_t
&
result
,
native_socket
fd
,
const
void
*
buf
,
size_t
len
);
...
...
@@ -43,17 +43,18 @@ public:
const
char
*
openssl_passphrase
();
private:
SSL_CTX
*
create_ssl_context
(
actor_system
&
sys
);
SSL_CTX
*
create_ssl_context
();
std
::
string
get_ssl_error
();
void
raise_ssl_error
(
std
::
string
msg
);
bool
handle_ssl_result
(
int
ret
);
SSL_CTX
*
ctx
;
SSL
*
ssl
;
actor_system
&
sys_
;
SSL_CTX
*
ctx_
;
SSL
*
ssl_
;
std
::
string
openssl_passphrase_
;
};
}
// namespace openssl
}
// namespace caf
#endif // CAF_OPENSSL_S
SL_S
ESSION_HPP
#endif // CAF_OPENSSL_SESSION_HPP
libcaf_openssl/src/manager.cpp
View file @
1e81bfb5
...
...
@@ -58,17 +58,14 @@ void manager::stop() {
void
manager
::
init
(
actor_system_config
&
)
{
CAF_LOG_TRACE
(
""
);
ERR_load_crypto_strings
();
OPENSSL_add_all_algorithms_conf
();
SSL_library_init
();
SSL_load_error_strings
();
if
(
authentication_enabled
())
{
if
(
!
system
().
config
().
openssl_certificate
.
size
()
)
if
(
system
().
config
().
openssl_certificate
.
size
()
==
0
)
CAF_RAISE_ERROR
(
"No certificate configured for SSL endpoint"
);
if
(
!
system
().
config
().
openssl_key
.
size
())
if
(
system
().
config
().
openssl_key
.
size
()
==
0
)
CAF_RAISE_ERROR
(
"No private key configured for SSL endpoint"
);
}
}
...
...
@@ -83,9 +80,9 @@ void* manager::subtype_ptr() {
bool
manager
::
authentication_enabled
()
{
auto
&
cfg
=
system
().
config
();
return
cfg
.
openssl_certificate
.
size
()
||
cfg
.
openssl_key
.
size
()
||
cfg
.
openssl_passphrase
.
size
()
||
cfg
.
openssl_capath
.
size
()
||
cfg
.
openssl_cafile
.
size
();
return
cfg
.
openssl_certificate
.
size
()
>
0
||
cfg
.
openssl_key
.
size
()
>
0
||
cfg
.
openssl_passphrase
.
size
()
>
0
||
cfg
.
openssl_capath
.
size
()
>
0
||
cfg
.
openssl_cafile
.
size
()
>
0
;
}
actor_system
::
module
*
manager
::
make
(
actor_system
&
sys
,
detail
::
type_list
<>
)
{
...
...
libcaf_openssl/src/middleman_actor.cpp
View file @
1e81bfb5
...
...
@@ -39,7 +39,7 @@
#include "caf/io/network/interfaces.hpp"
#include "caf/io/network/default_multiplexer.hpp"
#include "caf/openssl/s
sl_s
ession.hpp"
#include "caf/openssl/session.hpp"
namespace
caf
{
namespace
openssl
{
...
...
@@ -50,53 +50,47 @@ using native_socket = io::network::native_socket;
using
default_mpx
=
io
::
network
::
default_multiplexer
;
struct
ssl_policy
{
ssl_policy
(
std
::
shared_ptr
<
ssl_session
>
ssl
)
:
ssl_
(
ssl
)
{
ssl_policy
(
intrusive_ptr
<
session
>
session
)
:
session_
(
std
::
move
(
session
)
)
{
}
bool
read_some
(
size_t
&
result
,
native_socket
fd
,
void
*
buf
,
size_t
len
)
{
CAF_LOG_TRACE
(
CAF_ARG
(
fd
)
<<
CAF_ARG
(
len
));
return
ssl_
->
read_some
(
result
,
fd
,
buf
,
len
);
return
session_
->
read_some
(
result
,
fd
,
buf
,
len
);
}
bool
write_some
(
size_t
&
result
,
native_socket
fd
,
const
void
*
buf
,
size_t
len
)
{
CAF_LOG_TRACE
(
CAF_ARG
(
fd
)
<<
CAF_ARG
(
len
));
return
ssl_
->
write_some
(
result
,
fd
,
buf
,
len
);
return
session_
->
write_some
(
result
,
fd
,
buf
,
len
);
}
bool
try_accept
(
native_socket
&
result
,
native_socket
fd
)
{
CAF_LOG_TRACE
(
CAF_ARG
(
fd
));
sockaddr_storage
addr
;
memset
(
&
addr
,
0
,
sizeof
(
addr
));
socklen_t
addrlen
=
sizeof
(
addr
);
result
=
::
accept
(
fd
,
reinterpret_cast
<
sockaddr
*>
(
&
addr
),
&
addrlen
);
result
=
accept
(
fd
,
reinterpret_cast
<
sockaddr
*>
(
&
addr
),
&
addrlen
);
CAF_LOG_DEBUG
(
CAF_ARG
(
fd
)
<<
CAF_ARG
(
result
));
if
(
result
==
io
::
network
::
invalid_native_socket
)
{
auto
err
=
io
::
network
::
last_socket_error
();
if
(
!
io
::
network
::
would_block_or_temporarily_unavailable
(
err
))
return
false
;
}
return
ssl_
->
try_accept
(
result
);
return
session_
->
try_accept
(
result
);
}
private:
std
::
shared_ptr
<
ssl_session
>
ssl
_
;
intrusive_ptr
<
session
>
session
_
;
};
class
scribe_impl
:
public
io
::
scribe
{
public:
scribe_impl
(
default_mpx
&
mpx
,
native_socket
sockfd
,
std
::
shared_ptr
<
ssl_session
>
ssl
)
intrusive_ptr
<
session
>
session
)
:
scribe
(
io
::
network
::
conn_hdl_from_socket
(
sockfd
)),
launched_
(
false
),
stream_
(
mpx
,
sockfd
,
s
sl
)
{
stream_
(
mpx
,
sockfd
,
s
ession
)
{
// nop
}
...
...
@@ -168,10 +162,10 @@ class scribe_impl : public io::scribe {
class
doorman_impl
:
public
io
::
doorman
{
public:
doorman_impl
(
default_mpx
&
mx
,
native_socket
sockfd
,
std
::
shared_ptr
<
ssl_session
>
ssl
)
intrusive_ptr
<
session
>
session
)
:
doorman
(
io
::
network
::
accept_hdl_from_socket
(
sockfd
)),
acceptor_
(
mx
,
sockfd
,
s
sl
),
s
sl_
(
ssl
)
{
acceptor_
(
mx
,
sockfd
,
s
ession
),
s
ession_
(
std
::
move
(
session
)
)
{
// nop
}
...
...
@@ -185,7 +179,7 @@ public:
return
false
;
auto
&
dm
=
acceptor_
.
backend
();
auto
sptr
=
make_counted
<
scribe_impl
>
(
dm
,
acceptor_
.
accepted_socket
(),
s
sl
_
);
make_counted
<
scribe_impl
>
(
dm
,
acceptor_
.
accepted_socket
(),
s
ession
_
);
auto
hdl
=
sptr
->
hdl
();
parent
()
->
add_scribe
(
std
::
move
(
sptr
));
return
doorman
::
new_connection
(
&
dm
,
hdl
);
...
...
@@ -226,7 +220,7 @@ public:
private:
io
::
network
::
acceptor_impl
<
ssl_policy
>
acceptor_
;
std
::
shared_ptr
<
ssl_session
>
ssl
_
;
intrusive_ptr
<
session
>
session
_
;
};
class
middleman_actor_impl
:
public
io
::
middleman_actor_impl
{
...
...
@@ -240,14 +234,11 @@ protected:
expected
<
io
::
scribe_ptr
>
connect
(
const
std
::
string
&
host
,
uint16_t
port
)
override
{
auto
fd
=
io
::
network
::
new_tcp_connection
(
host
,
port
);
if
(
!
fd
)
if
(
fd
==
io
::
network
::
invalid_native_socket
)
return
std
::
move
(
fd
.
error
());
auto
ssl
=
std
::
make_shared
<
ssl_session
>
(
system
());
if
(
ssl
->
connect
(
*
fd
))
return
make_counted
<
scribe_impl
>
(
mpx
(),
*
fd
,
ssl
);
auto
session
=
new
class
session
(
system
());
if
(
session
->
connect
(
*
fd
))
return
make_counted
<
scribe_impl
>
(
mpx
(),
*
fd
,
session
);
else
return
sec
::
cannot_connect_to_node
;
}
...
...
@@ -255,13 +246,10 @@ protected:
expected
<
io
::
doorman_ptr
>
open
(
uint16_t
port
,
const
char
*
addr
,
bool
reuse
)
override
{
auto
fd
=
io
::
network
::
new_tcp_acceptor_impl
(
port
,
addr
,
reuse
);
if
(
!
fd
)
if
(
fd
==
io
::
network
::
invalid_native_socket
)
return
std
::
move
(
fd
.
error
());
auto
ssl
=
std
::
make_shared
<
ssl_session
>
(
system
());
return
make_counted
<
doorman_impl
>
(
mpx
(),
*
fd
,
ssl
);
auto
session
=
new
class
session
(
system
());
return
make_counted
<
doorman_impl
>
(
mpx
(),
*
fd
,
session
);
}
private:
...
...
libcaf_openssl/src/s
sl_s
ession.cpp
→
libcaf_openssl/src/session.cpp
View file @
1e81bfb5
...
...
@@ -17,10 +17,12 @@
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#include "caf/openssl/s
sl_s
ession.hpp"
#include "caf/openssl/session.hpp"
#include <sys/socket.h>
#include <openssl/err.h>
#include "caf/actor_system_config.hpp"
#include "caf/openssl/manager.hpp"
...
...
@@ -29,28 +31,27 @@ namespace openssl {
static
int
pem_passwd_cb
(
char
*
buf
,
int
size
,
int
rwflag
,
void
*
session
);
ssl_session
::
ssl_session
(
actor_system
&
sys
)
{
ctx
=
create_ssl_context
(
sys
);
ssl
=
SSL_new
(
ctx
);
session
::
session
(
actor_system
&
sys
)
:
sys_
(
sys
)
{
}
if
(
!
ssl
)
void
session
::
init
()
{
ctx_
=
create_ssl_context
();
ssl_
=
SSL_new
(
ctx_
);
if
(
!
ssl_
)
CAF_RAISE_ERROR
(
"cannot create SSL session"
);
}
s
sl_session
::~
ssl_
session
()
{
SSL_free
(
ssl
);
SSL_CTX_free
(
ctx
);
s
ession
::~
session
()
{
SSL_free
(
ssl
_
);
SSL_CTX_free
(
ctx
_
);
}
bool
s
sl_session
::
read_some
(
size_t
&
result
,
native_socket
fd
,
void
*
buf
,
size_t
len
)
{
bool
s
ession
::
read_some
(
size_t
&
result
,
native_socket
/* fd */
,
void
*
buf
,
size_t
len
)
{
CAF_LOG_TRACE
(
CAF_ARG
(
fd
)
<<
CAF_ARG
(
len
));
if
(
len
==
0
)
return
0
;
auto
ret
=
SSL_read
(
ssl
,
buf
,
len
);
auto
ret
=
SSL_read
(
ssl_
,
buf
,
len
);
if
(
ret
>
0
)
{
result
=
ret
;
return
true
;
...
...
@@ -60,15 +61,12 @@ bool ssl_session::read_some(size_t& result, native_socket fd, void* buf,
}
}
bool
s
sl_session
::
write_some
(
size_t
&
result
,
native_socket
fd
,
const
void
*
buf
,
size_t
len
)
{
bool
s
ession
::
write_some
(
size_t
&
result
,
native_socket
/* fd */
,
const
void
*
buf
,
size_t
len
)
{
CAF_LOG_TRACE
(
CAF_ARG
(
fd
)
<<
CAF_ARG
(
len
));
if
(
len
==
0
)
return
true
;
auto
ret
=
SSL_write
(
ssl
,
buf
,
len
);
auto
ret
=
SSL_write
(
ssl_
,
buf
,
len
);
if
(
ret
>
0
)
{
result
=
ret
;
return
true
;
...
...
@@ -78,71 +76,60 @@ bool ssl_session::write_some(size_t& result, native_socket fd, const void* buf,
}
}
bool
s
sl_s
ession
::
connect
(
native_socket
fd
)
{
SSL_set_fd
(
ssl
,
fd
);
SSL_set_
connect_state
(
ssl
);
auto
ret
=
SSL_connect
(
ssl
);
bool
session
::
connect
(
native_socket
fd
)
{
init
(
);
SSL_set_
fd
(
ssl_
,
fd
);
SSL_set_connect_state
(
ssl_
);
auto
ret
=
SSL_connect
(
ssl
_
);
return
ret
>
0
||
handle_ssl_result
(
ret
);
}
bool
ssl_session
::
try_accept
(
native_socket
fd
)
{
SSL_set_fd
(
ssl
,
fd
);
SSL_set_accept_state
(
ssl
);
auto
ret
=
SSL_accept
(
ssl
);
bool
session
::
try_accept
(
native_socket
fd
)
{
init
();
SSL_set_fd
(
ssl_
,
fd
);
SSL_set_accept_state
(
ssl_
);
auto
ret
=
SSL_accept
(
ssl_
);
if
(
ret
>
0
)
return
true
;
else
return
handle_ssl_result
(
ret
);
}
const
char
*
s
sl_s
ession
::
openssl_passphrase
()
{
const
char
*
session
::
openssl_passphrase
()
{
return
openssl_passphrase_
.
c_str
();
}
SSL_CTX
*
s
sl_session
::
create_ssl_context
(
actor_system
&
sys
)
{
SSL_CTX
*
s
ession
::
create_ssl_context
(
)
{
auto
ctx
=
SSL_CTX_new
(
TLSv1_2_method
());
if
(
!
ctx
)
raise_ssl_error
(
"cannot create OpenSSL context"
);
if
(
sys
.
openssl_manager
().
authentication_enabled
())
{
if
(
sys_
.
openssl_manager
().
authentication_enabled
())
{
// Require valid certificates on both sides.
auto
&
cfg
=
sys
.
config
();
if
(
cfg
.
openssl_certificate
.
size
()
auto
&
cfg
=
sys_
.
config
();
if
(
cfg
.
openssl_certificate
.
size
()
>
0
&&
SSL_CTX_use_certificate_chain_file
(
ctx
,
cfg
.
openssl_certificate
.
c_str
())
!=
1
)
raise_ssl_error
(
"cannot load certificate"
);
if
(
cfg
.
openssl_passphrase
.
size
())
{
if
(
cfg
.
openssl_passphrase
.
size
()
>
0
)
{
openssl_passphrase_
=
cfg
.
openssl_passphrase
;
SSL_CTX_set_default_passwd_cb
(
ctx
,
pem_passwd_cb
);
SSL_CTX_set_default_passwd_cb_userdata
(
ctx
,
(
void
*
)
this
);
}
if
(
cfg
.
openssl_key
.
size
()
if
(
cfg
.
openssl_key
.
size
()
>
0
&&
SSL_CTX_use_PrivateKey_file
(
ctx
,
cfg
.
openssl_key
.
c_str
(),
SSL_FILETYPE_PEM
)
!=
1
)
raise_ssl_error
(
"cannot load private key"
);
auto
cafile
=
(
cfg
.
openssl_cafile
.
size
()
?
cfg
.
openssl_cafile
.
c_str
()
:
nullptr
);
(
cfg
.
openssl_cafile
.
size
()
>
0
?
cfg
.
openssl_cafile
.
c_str
()
:
nullptr
);
auto
capath
=
(
cfg
.
openssl_capath
.
size
()
?
cfg
.
openssl_capath
.
c_str
()
:
nullptr
);
(
cfg
.
openssl_capath
.
size
()
>
0
?
cfg
.
openssl_capath
.
c_str
()
:
nullptr
);
if
(
cafile
||
capath
)
{
if
(
SSL_CTX_load_verify_locations
(
ctx
,
cafile
,
capath
)
!=
1
)
raise_ssl_error
(
"cannot load trusted CA certificates"
);
}
SSL_CTX_set_verify
(
ctx
,
SSL_VERIFY_PEER
|
SSL_VERIFY_FAIL_IF_NO_PEER_CERT
,
nullptr
);
if
(
SSL_CTX_set_cipher_list
(
ctx
,
"HIGH:!aNULL:!MD5"
)
!=
1
)
raise_ssl_error
(
"cannot set cipher list"
);
}
...
...
@@ -150,13 +137,10 @@ SSL_CTX* ssl_session::create_ssl_context(actor_system& sys) {
else
{
// No authentication.
SSL_CTX_set_verify
(
ctx
,
SSL_VERIFY_NONE
,
nullptr
);
auto
ecdh
=
EC_KEY_new_by_curve_name
(
NID_secp384r1
);
if
(
!
ecdh
)
raise_ssl_error
(
"cannot get ECDH curve"
);
SSL_CTX_set_tmp_ecdh
(
ctx
,
ecdh
);
if
(
SSL_CTX_set_cipher_list
(
ctx
,
"AECDH-AES256-SHA"
)
!=
1
)
raise_ssl_error
(
"cannot set anonymous cipher"
);
}
...
...
@@ -164,37 +148,31 @@ SSL_CTX* ssl_session::create_ssl_context(actor_system& sys) {
return
ctx
;
}
std
::
string
s
sl_s
ession
::
get_ssl_error
()
{
std
::
string
session
::
get_ssl_error
()
{
std
::
string
msg
=
""
;
while
(
auto
err
=
ERR_get_error
())
{
if
(
msg
.
size
())
if
(
msg
.
size
()
>
0
)
msg
+=
" "
;
char
buf
[
256
];
ERR_error_string_n
(
err
,
buf
,
sizeof
(
buf
));
msg
+=
buf
;
}
return
msg
;
}
void
s
sl_s
ession
::
raise_ssl_error
(
std
::
string
msg
)
{
void
session
::
raise_ssl_error
(
std
::
string
msg
)
{
CAF_RAISE_ERROR
(
std
::
string
(
"[OpenSSL] "
)
+
msg
+
": "
+
get_ssl_error
());
}
bool
ssl_session
::
handle_ssl_result
(
int
ret
)
{
auto
err
=
SSL_get_error
(
ssl
,
ret
);
bool
session
::
handle_ssl_result
(
int
ret
)
{
auto
err
=
SSL_get_error
(
ssl_
,
ret
);
switch
(
err
)
{
case
SSL_ERROR_WANT_READ
:
// Try again next time.
case
SSL_ERROR_WANT_WRITE
:
return
true
;
case
SSL_ERROR_ZERO_RETURN
:
// Regular remote connection shutdown.
case
SSL_ERROR_SYSCALL
:
// Socket connection closed.
return
false
;
default:
// Other error
// TODO: Log somehow?
// auto msg = get_ssl_error();
...
...
@@ -203,7 +181,7 @@ bool ssl_session::handle_ssl_result(int ret) {
}
static
int
pem_passwd_cb
(
char
*
buf
,
int
size
,
int
/* rwflag */
,
void
*
session
)
{
auto
passphrase
=
static_cast
<
ssl_
session
*>
(
session
)
->
openssl_passphrase
();
auto
passphrase
=
static_cast
<
class
session
*>
(
session
)
->
openssl_passphrase
();
strncpy
(
buf
,
passphrase
,
size
);
buf
[
size
-
1
]
=
'\0'
;
return
strlen
(
buf
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment