Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed the SHM segment smashing while reading with security <master> #1646

Merged
merged 7 commits into from
Jan 11, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion include/fastdds/rtps/messages/MessageReceiver.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,11 @@ class MessageReceiver
Time_t timestamp_;

#if HAVE_SECURITY
//!Buffer to process the decoded RTPS message
CDRMessage_t crypto_msg_;
//!Buffer to process each decoded RTPS sub-message
CDRMessage_t crypto_submsg_;
//!Buffer to process a decoded payload
SerializedPayload_t crypto_payload_;
#endif // if HAVE_SECURITY

Expand All @@ -106,7 +110,6 @@ class MessageReceiver
uint32_t,
uint16_t)> process_data_fragment_message_function_;


//!Reset the MessageReceiver to process a new message.
void reset();

Expand Down
8 changes: 6 additions & 2 deletions src/cpp/rtps/messages/MessageReceiver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ MessageReceiver::MessageReceiver(
, timestamp_(c_TimeInvalid)
#if HAVE_SECURITY
, crypto_msg_(participant->is_secure() ? rec_buffer_size : 0)
, crypto_submsg_(participant->is_secure() ? rec_buffer_size : 0)
, crypto_payload_(participant->is_secure() ? rec_buffer_size : 0)
#endif // if HAVE_SECURITY
{
Expand Down Expand Up @@ -347,8 +348,11 @@ void MessageReceiver::processCDRMsg(

if (decode_ret == 0)
{
// Swap
std::swap(msg, auxiliary_buffer);
// The original CDRMessage buffer (msg) now points to the proprietary temporary buffer crypto_msg_.
// The auxiliary buffer now points to the propietary temporary buffer crypto_submsg_.
// This way each decoded sub-message will be processed using the crypto_submsg_ buffer.
msg = auxiliary_buffer;
auxiliary_buffer = &crypto_submsg_;
}
#endif // if HAVE_SECURITY

Expand Down
65 changes: 65 additions & 0 deletions test/communication/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,20 @@ if(NOT ((MSVC OR MSVC_IDE) AND EPROSIMA_INSTALLER) AND fastcdr_FOUND)
${CMAKE_CURRENT_BINARY_DIR}/liveliness_assertion.120.xml COPYONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/liveliness_assertion.360.xml
${CMAKE_CURRENT_BINARY_DIR}/liveliness_assertion.360.xml COPYONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/multiple_subs_secure_crypto_communication.py
${CMAKE_CURRENT_BINARY_DIR}/multiple_subs_secure_crypto_communication.py COPYONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/secure_msg_crypto_besteffort_pub.xml
${CMAKE_CURRENT_BINARY_DIR}/secure_msg_crypto_besteffort_pub.xml COPYONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/secure_msg_crypto_besteffort_sub.xml
${CMAKE_CURRENT_BINARY_DIR}/secure_msg_crypto_besteffort_sub.xml COPYONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/secure_msg_submsg_crypto_besteffort_pub.xml
${CMAKE_CURRENT_BINARY_DIR}/secure_msg_submsg_crypto_besteffort_pub.xml COPYONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/secure_msg_submsg_crypto_besteffort_sub.xml
${CMAKE_CURRENT_BINARY_DIR}/secure_msg_submsg_crypto_besteffort_sub.xml COPYONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/secure_submsg_crypto_besteffort_pub.xml
${CMAKE_CURRENT_BINARY_DIR}/secure_submsg_crypto_besteffort_pub.xml COPYONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/secure_submsg_crypto_besteffort_sub.xml
${CMAKE_CURRENT_BINARY_DIR}/secure_submsg_crypto_besteffort_sub.xml COPYONLY)
if(SECURITY)
configure_file(${PROJECT_SOURCE_DIR}/test/certs/maincacert.pem
${CMAKE_CURRENT_BINARY_DIR}/maincacert.pem COPYONLY)
Expand Down Expand Up @@ -214,6 +228,57 @@ if(NOT ((MSVC OR MSVC_IDE) AND EPROSIMA_INSTALLER) AND fastcdr_FOUND)
set_property(TEST SimpleCommunicationSecureBestEffort APPEND PROPERTY ENVIRONMENT
"PATH=$<TARGET_FILE_DIR:${PROJECT_NAME}>\\;$<TARGET_FILE_DIR:fastcdr>\\;${WIN_PATH}")
endif()

add_test(NAME SimpleCommunicationSecureMsgCryptoBestEffort
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/multiple_subs_secure_crypto_communication.py
--pub $<TARGET_FILE:SimpleCommunicationPublisher>
--xml-pub secure_msg_crypto_besteffort_pub.xml
--sub $<TARGET_FILE:SimpleCommunicationSubscriber>
--xml-sub secure_msg_crypto_besteffort_sub.xml
--samples 10 --wait 2 --n-subs 5)

# Set test with label NoMemoryCheck
set_property(TEST SimpleCommunicationSecureMsgCryptoBestEffort PROPERTY LABELS "NoMemoryCheck")

if(WIN32)
string(REPLACE ";" "\\;" WIN_PATH "$ENV{PATH}")
set_property(TEST SimpleCommunicationSecureMsgCryptoBestEffort APPEND PROPERTY ENVIRONMENT
"PATH=$<TARGET_FILE_DIR:${PROJECT_NAME}>\\;$<TARGET_FILE_DIR:fastcdr>\\;${WIN_PATH}")
endif()

add_test(NAME SimpleCommunicationSecureMsgSubmsgCryptoBestEffort
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/multiple_subs_secure_crypto_communication.py
--pub $<TARGET_FILE:SimpleCommunicationPublisher>
--xml-pub secure_msg_submsg_crypto_besteffort_pub.xml
--sub $<TARGET_FILE:SimpleCommunicationSubscriber>
--xml-sub secure_msg_submsg_crypto_besteffort_sub.xml
--samples 10 --wait 2 --n-subs 5)

# Set test with label NoMemoryCheck
set_property(TEST SimpleCommunicationSecureMsgSubmsgCryptoBestEffort PROPERTY LABELS "NoMemoryCheck")

if(WIN32)
string(REPLACE ";" "\\;" WIN_PATH "$ENV{PATH}")
set_property(TEST SimpleCommunicationSecureMsgSubmsgCryptoBestEffort APPEND PROPERTY ENVIRONMENT
"PATH=$<TARGET_FILE_DIR:${PROJECT_NAME}>\\;$<TARGET_FILE_DIR:fastcdr>\\;${WIN_PATH}")
endif()

add_test(NAME SimpleCommunicationSecureSubmsgCryptoBestEffort
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/multiple_subs_secure_crypto_communication.py
--pub $<TARGET_FILE:SimpleCommunicationPublisher>
--xml-pub secure_submsg_crypto_besteffort_pub.xml
--sub $<TARGET_FILE:SimpleCommunicationSubscriber>
--xml-sub secure_submsg_crypto_besteffort_sub.xml
--samples 10 --wait 2 --n-subs 5)

# Set test with label NoMemoryCheck
set_property(TEST SimpleCommunicationSecureSubmsgCryptoBestEffort PROPERTY LABELS "NoMemoryCheck")

if(WIN32)
string(REPLACE ";" "\\;" WIN_PATH "$ENV{PATH}")
set_property(TEST SimpleCommunicationSecureSubmsgCryptoBestEffort APPEND PROPERTY ENVIRONMENT
"PATH=$<TARGET_FILE_DIR:${PROJECT_NAME}>\\;$<TARGET_FILE_DIR:fastcdr>\\;${WIN_PATH}")
endif()
endif()

add_test(NAME LivelinessAssertion
Expand Down
188 changes: 188 additions & 0 deletions test/communication/multiple_subs_secure_crypto_communication.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
# Copyright 2020 Proyectos y Sistemas de Mantenimiento SL (eProsima).
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Script to test the secure communication with encrypted RTPS messages."""
import argparse
import os
import subprocess
import sys


class ParseOptions():
"""Parse arguments."""

def __init__(self):
"""Object constructor."""
self.args = self.__parse_args()

def __parse_args(self):
"""
Parse the input arguments.

:return: A dictionary containing the arguments parsed.
"""
parser = argparse.ArgumentParser(
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
add_help=True,
description=(
'Script to test the secure communication with encrypted RTPS'
'messages.'),
)
parser.add_argument(
'-p',
'--pub',
type=str,
required=True,
help='Path to the Publisher executable.'
)
parser.add_argument(
'-s',
'--sub',
type=str,
required=True,
help='Path to the Subscriber executable.'
)
parser.add_argument(
'-P',
'--xml-pub',
type=str,
help='Path to the publisher xml configuration file.'
)
parser.add_argument(
'-S',
'--xml-sub',
type=str,
help='Path to the subscriber xml configuration file.'
)
parser.add_argument(
'-x',
'--xml',
type=str,
help=(
'Path to the xml configuration file containing publisher and'
'subscriber profiles.')
)
parser.add_argument(
'-w',
'--wait',
type=int,
help='Time for the publisher to wait for discovery.'
)
parser.add_argument(
'-a',
'--samples',
type=int,
help='Number of samples sent by the publisher.'
)
parser.add_argument(
'-n',
'--n-subs',
type=int,
help='Number of subscribers to launch.'
)

return parser.parse_args()


def run(args):
"""
Run the publisher and both susbcribers.

:param args: The input paramenters.

:return: The return code resulting from the publisher and subscribers
execution. It is the number of failed processes.
"""
pub_command = []
sub_command = []

script_dir = os.path.dirname(os.path.realpath(__file__))

if not os.path.isfile(args.pub):
print(f'Publisher executable file does not exists: {args.pub}')
sys.exit(1)

if not os.access(args.pub, os.X_OK):
print(
'Publisher executable does not have execution permissions:'
f'{args.pub}')

pub_command.append(args.pub)

if not os.path.isfile(args.sub):
print(f'Subscriber executable file does not exists: {args.sub}')
sys.exit(1)

if not os.access(args.sub, os.X_OK):
print(
'Subscriber executable does not have execution permissions:'
f'{args.sub}')
sys.exit(1)

sub_command.append(args.sub)

if args.xml:
xml_file_pub = os.path.join(script_dir, args.xml)
xml_file_sub = os.path.join(script_dir, args.xml)
elif args.xml_pub and args.xml_sub:
if args.xml_pub:
xml_file_pub = os.path.join(script_dir, args.xml_pub)
if args.xml_sub:
xml_file_sub = os.path.join(script_dir, args.xml_sub)
else:
print('Not provided xml configuration files.')
sys.exit(1)

pub_command.extend(['--xmlfile', xml_file_pub])
sub_command.extend(['--xmlfile', xml_file_sub])

pub_command.extend(['--seed', str(os.getpid())])
sub_command.extend(['--seed', str(os.getpid())])

if args.wait:
pub_command.extend(['--wait', str(args.wait)])

if args.samples:
pub_command.extend(['--samples', str(args.samples)])
sub_command.extend(['--samples', str(args.samples)])

sub_processes = []
for i in range(args.n_subs):
sub_processes.append(subprocess.Popen(sub_command))
print(
f'Running Subscriber {i+1} - commmand: ',
' '.join(map(str, sub_command)))

pub_proc = subprocess.Popen(pub_command)
print(
'Running Publisher - commmand: ',
' '.join(map(str, pub_command)))

failed_subs = 0
for sub, sub_proc in enumerate(sub_processes):
sub_proc.communicate()
if sub_proc.returncode != 0:
print(f'Subscriber {sub+1} failed while running.')
failed_subs += 1

pub_proc.kill()

sys.exit(failed_subs)


if __name__ == '__main__':

# Parse arguments
args = ParseOptions()

run(args.args)
60 changes: 60 additions & 0 deletions test/communication/secure_msg_crypto_besteffort_pub.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?xml version="1.0" encoding="UTF-8" ?>
<dds xmlns="http://www.eprosima.com/XMLSchemas/fastRTPS_Profiles" >
<profiles>
<transport_descriptors>
<transport_descriptor>
<transport_id>shm_transport</transport_id>
<type>SHM</type>
</transport_descriptor>
</transport_descriptors>

<participant profile_name="secure_participant_profile" is_default_profile="true">
<rtps>
<userTransports>
<transport_id>shm_transport</transport_id>
</userTransports>
<useBuiltinTransports>false</useBuiltinTransports>
<propertiesPolicy>
<properties>
<!-- Activate DDS:Auth:PKI-DH plugin -->
<property>
<name>dds.sec.auth.plugin</name>
<value>builtin.PKI-DH</value>
</property>
<!-- Configure DDS:Auth:PKI-DH plugin -->
<property>
<name>dds.sec.auth.builtin.PKI-DH.identity_ca</name>
<value>file://maincacert.pem</value>
</property>
<property>
<name>dds.sec.auth.builtin.PKI-DH.identity_certificate</name>
<value>file://mainpubcert.pem</value>
</property>
<property>
<name>dds.sec.auth.builtin.PKI-DH.private_key</name>
<value>file://mainpubkey.pem</value>
</property>
<!-- Activate DDS:Crypto:AES-GCM-GMAC plugin -->
<property>
<name>dds.sec.crypto.plugin</name>
<value>builtin.AES-GCM-GMAC</value>
</property>
<!-- Configure DDS:Crypto:AES-GCM-GMAC plugin -->
<property>
<name>rtps.participant.rtps_protection_kind</name>
<value>ENCRYPT</value>
</property>
</properties>
</propertiesPolicy>
</rtps>
</participant>

<publisher profile_name="secure_publisher_profile" is_default_profile="true">
<qos>
<reliability>
<kind>BEST_EFFORT</kind>
</reliability>
</qos>
</publisher>
</profiles>
</dds>
Loading