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

Add security logging base class #1

Merged

Conversation

artivis
Copy link

@artivis artivis commented Feb 4, 2020

Add security logging plugin base class and accompanying basic classes as defined in DDS-Sec specs.

Note: whereas specs define some long-based enum I went ahead and used long-based enum struct instead.

Signed-off-by: artivis jeremie.deray@canonical.com

Signed-off-by: artivis <jeremie.deray@canonical.com>
Signed-off-by: artivis <jeremie.deray@canonical.com>
Signed-off-by: artivis <jeremie.deray@canonical.com>
Signed-off-by: artivis <jeremie.deray@canonical.com>
Signed-off-by: artivis <jeremie.deray@canonical.com>
Signed-off-by: artivis <jeremie.deray@canonical.com>
* @note Definition in DDS-Sec v1.1 9.6
*/
struct BuiltinLoggingType final {
octet facility; // Set to 0x0A (10). Indicates sec/auth msgs
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fast RTPS seems to use four spaces for indentation. This only seems to be a single space, and elsewhere in the PR there are two. We should probably follow their established format. Try to make the code look like it was written by them.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I will take care of 'fixing' all indentations...

/**
* @brief The EventLogLevel enum
*
* @note Definition in DDS-Sec v1.1 8.6.2.1.1
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This section seems to outline the same information as 9.6, but with different names. I suspect we can remove this struct and use LoggingLevel instead, which seems to be what RTI has done. We should say something on the RTI forums or ping eProsima to make sure we're right, and to raise awareness of the error.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

*/
class Logging
{
public:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check other classes in Fast RTPS, make sure we're following the same format (I think these are indented).

/**
* @brief set_log_options
* @param log_options
* @return TRUE if successful
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could probably flesh out the descriptions using the spec.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will document properly once the actual implementation is done.

src/cpp/rtps/security/logging/Logging.cpp Outdated Show resolved Hide resolved
src/cpp/rtps/security/logging/Logging.cpp Outdated Show resolved Hide resolved
//TODO(artivis): set up DataWriter/Publisher
}

return true;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we handle the case where a log file wasn't provided, and distribute is false? Does that seem like an error?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that's an error but maybe we should warn somehow.

@canonical canonical deleted a comment from artivis Feb 6, 2020
Signed-off-by: artivis <jeremie.deray@canonical.com>
Signed-off-by: artivis <jeremie.deray@canonical.com>
Signed-off-by: artivis <jeremie.deray@canonical.com>
Signed-off-by: artivis <jeremie.deray@canonical.com>
Signed-off-by: artivis <jeremie.deray@canonical.com>
Signed-off-by: artivis <jeremie.deray@canonical.com>
Signed-off-by: artivis <jeremie.deray@canonical.com>
Signed-off-by: artivis <jeremie.deray@canonical.com>
Signed-off-by: artivis <jeremie.deray@canonical.com>
* @brief Whether the options are set or not.
* @return True if the options are set.
*/
inline bool options_set() const { return options_set_; }
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a use-case for having this public instead of protected?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Options must be set before calling enable. This seemed like a handy way to assert that options are indeed set. But maybe it is not necessary at all.

include/fastdds/rtps/security/logging/BuiltinLogging.h Outdated Show resolved Hide resolved
include/fastdds/rtps/security/logging/BuiltinLogging.h Outdated Show resolved Hide resolved
src/cpp/rtps/security/SecurityManager.cpp Show resolved Hide resolved
Comment on lines 10 to 32
, thread_([this]() {
BuiltinLoggingType msg;
for (;;)
{
// Put the thread asleep until there is
// something to process
MessagePtr p = queue_.wait_pop();

if (!p)
{
if (stop_)
{
return;
}
continue;
}

msg = convert(*p);

publish(msg);
}
})
{
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it'd be easier to maintain if this were a standalone function in an anonymous namespace as opposed to a lambda.

std::unique_lock<std::mutex> lock(mutex_);
while (queue_.empty())
{
has_data_.wait(lock);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First of all, I suggest getting rid of the while and just using the predicate, e.g.

has_data_.wait(lock, [&]{ return !queue_.empty(); });

However, this design requires all users of this class to utilize the hack that you have in the BuiltinLogging class' destructor, pushing an empty message on to force a thread wakeup. I recommend a few things that could help this limitation.

First of all, add a stop_ atomic bool member variable (default false, obviously). Then update the predicate here to be:

has_data_.wait(lock, [&]{ return !stop_.load() && !queue_.empty(); });

Second, add another public member function for stopping:

void ConcurrentQueue::stop()
{
    stop_ = true;
    has_data_.notify_all();
}

Finally, add a destructor that looks something like:

ConcurrentQueue::~ConcurrentQueue()
{
    stop();
}

These together will cause all clients waiting on data from this to wake up and realize that no further data will be forthcoming once the queue is destroyed without hack needed. Sadly, in your case, given that you own the thread and the queue in the same scope, without a refactor you'll need to use the stop() function before waiting for the thread to join.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the while as suggested although it is equivalent.

While the current schema may look hacky, it allows for a desirable feature, the possibility to log all messages stored in the queue prior to the 'stop' call. Given that the logging is the last security object to be destroyed, other security plugins may still have messages to log upon destruction, which is possible here.

Furthermore, I don't like adding a stop mechanism to the queue, it seems very odd to 'stop' a container...
We could abstract the queue and thread in a class but that only make sense if it is re-used somewhere else. I'll leave it as is for now but re-visit it later on see if there is a better design.

include/fastrtps/utils/concurrent_queue.h Outdated Show resolved Hide resolved

if (!p)
{
if (stop_)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you follow my advice about the queue's destructor and notification, you should be able to do away with this member variable entirely and just use the invalid return value as the signal that the thread should shutdown.

Signed-off-by: artivis <jeremie.deray@canonical.com>
Signed-off-by: artivis <jeremie.deray@canonical.com>
Signed-off-by: artivis <jeremie.deray@canonical.com>
Signed-off-by: artivis <jeremie.deray@canonical.com>
Signed-off-by: artivis <jeremie.deray@canonical.com>
Signed-off-by: artivis <jeremie.deray@canonical.com>
Signed-off-by: artivis <jeremie.deray@canonical.com>
Signed-off-by: artivis <jeremie.deray@canonical.com>
Signed-off-by: artivis <jeremie.deray@canonical.com>
Signed-off-by: artivis <jeremie.deray@canonical.com>
Signed-off-by: artivis <jeremie.deray@canonical.com>
Signed-off-by: artivis <jeremie.deray@canonical.com>
Signed-off-by: artivis <jeremie.deray@canonical.com>
Signed-off-by: artivis <jeremie.deray@canonical.com>
Signed-off-by: artivis <jeremie.deray@canonical.com>
Signed-off-by: artivis <jeremie.deray@canonical.com>
LoggingLevel& l,
SecurityException& e)
{
//TODO(artivis): use an array of const char to avoid strings?
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest going the other way and extracting this whole logic into a map.

Signed-off-by: artivis <jeremie.deray@canonical.com>
Signed-off-by: artivis <jeremie.deray@canonical.com>
Comment on lines +135 to +138
template <typename Stream>
bool compose_header(Stream& header,
const BuiltinLoggingType& builtin_msg,
SecurityException& exception) const;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume DDS support will also be streamable? Or do you plan on streaming to an sstream or something? Because that would also work for the file logging. Do we really gain much by having this be a template?

Signed-off-by: artivis <jeremie.deray@canonical.com>
Signed-off-by: artivis <jeremie.deray@canonical.com>
Signed-off-by: artivis <jeremie.deray@canonical.com>
Signed-off-by: artivis <jeremie.deray@canonical.com>
Signed-off-by: artivis <jeremie.deray@canonical.com>
@artivis artivis marked this pull request as ready for review April 2, 2020 19:16
@artivis artivis merged commit fa9250c into canonical:feature/security-logging Apr 2, 2020
artivis added a commit to artivis/Fast-RTPS that referenced this pull request May 29, 2020
* Add security logging (canonical#1)

* add security logging to file as per dds-spec
* add set/get logger to security plugin base classes
* logging integration to SecurityManager
* add SECURITY_LOGGING macros

Signed-off-by: artivis <jeremie.deray@canonical.com>

* handle empty filename

Signed-off-by: artivis <jeremie.deray@canonical.com>

* post-master-merge fix

Signed-off-by: artivis <jeremie.deray@canonical.com>

* handle empty filename

Signed-off-by: artivis <jeremie.deray@canonical.com>

* fix typo test filename

Signed-off-by: artivis <jeremie.deray@canonical.com>

* fix linking error

* some doc fixes

Signed-off-by: artivis <jeremie.deray@canonical.com>

* some doc fixes

Signed-off-by: artivis <jeremie.deray@canonical.com>

* support logging in SecurityPluginFactory Mock

Signed-off-by: artivis <jeremie.deray@canonical.com>

* include log in security logging for macro support & cleanup

Signed-off-by: artivis <jeremie.deray@canonical.com>

* add missing source

Signed-off-by: artivis <jeremie.deray@canonical.com>

* replace 'library' includes with 'system'

Signed-off-by: artivis <jeremie.deray@canonical.com>

* uncrustify

Signed-off-by: artivis <jeremie.deray@canonical.com>

* add log to file test

Signed-off-by: artivis <jeremie.deray@canonical.com>

* fix warnings

Signed-off-by: artivis <jeremie.deray@canonical.com>

* fix error msg typo

Signed-off-by: artivis <jeremie.deray@canonical.com>

* fix linking error

Signed-off-by: artivis <jeremie.deray@canonical.com>

* fix warning

Signed-off-by: artivis <jeremie.deray@canonical.com>

* add verbosity level to file logs

Signed-off-by: artivis <jeremie.deray@canonical.com>

* test file logs header

Signed-off-by: artivis <jeremie.deray@canonical.com>

* use logging in Permission

Signed-off-by: artivis <jeremie.deray@canonical.com>

* use logging in PKIDH

Signed-off-by: artivis <jeremie.deray@canonical.com>

* use logging in SecurityManager

Signed-off-by: artivis <jeremie.deray@canonical.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants