-
Notifications
You must be signed in to change notification settings - Fork 155
Feat[bmq, mqb]: Support TLS listeners #549
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
base: main
Are you sure you want to change the base?
Conversation
93f478c to
a1e957d
Compare
chrisbeard
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very quick pass on the draft
| "loggingVerbosity": "TRACE", | ||
| "consoleSeverityThreshold": "TRACE", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this change intentional?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, seems like a leftover from local testing
| ntca::EncryptionClientOptions encryptionClientOptions; | ||
| // Set the minimum version to TLS 1.3 | ||
| encryptionClientOptions.setMinMethod(ntca::EncryptionMethod::e_TLS_V1_3); | ||
| encryptionClientOptions.setMaxMethod(ntca::EncryptionMethod::e_TLS_V1_3); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Curious to see what others think here. From the ntc docs, it looks like we could use e_DEFAULT here. The client can then use v1.3 up to ntc's max supported version without needing to make code changes here (when 1.4 eventually lands)?
struct EncryptionMethod {
public:
/// Enumerate the methods of encryption.
enum Value {
/// When specified as a minimum version, the minimum version is
/// interpreted as the minimum version suggested by the current
/// standards of cryptography. When specified as a maximum version, the
/// maximum version is interpreted as the maximum version supported by
/// the implementation.
e_DEFAULT,
...7b352d4 to
634c1e4
Compare
| // A name of a property to put auto-incremented values | ||
| // in batch-posting mode. | ||
|
|
||
| bsl::string d_certificateAuthority; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's initialize this field in this constructor:
| Parameters::Parameters(bslma::Allocator* allocator) |
And add it to this printer:
| Parameters::print(bsl::ostream& stream, int level, int spacesPerLevel) const |
| statContextCreator, | ||
| const bmqp_ctrlmsg::NegotiationMessage& negotiationMessage, | ||
| BlobSpPool* blobSpPool, | ||
| bslma::Allocator* allocator) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The args list for this method can be rearranged so the non const ptrs (except allocator) go first. Can do it later
| void Application::ChannelFactoryPipeline::stop() | ||
| { | ||
| d_reconnectingChannelFactory.stop(); | ||
| d_channelFactory.stop(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bmqio::NtcChannelFactory d_channelFactory;
bmqio::ResolvingChannelFactory d_resolvingChannelFactory;
bmqio::ReconnectingChannelFactory d_reconnectingChannelFactory;
bmqio::StatChannelFactory d_statChannelFactory;
NegotiatedChannelFactory d_negotiatedChannelFactory;
There are 5 different factories stored as fields, should all of them be stopped here? Or either there should be a comment that some of these factories are stopped from other factories that hold them.
| return bmqt::GenericResult::e_SUCCESS; | ||
| } | ||
|
|
||
| void Application::ChannelFactoryPipeline::stop() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we miss calling stop in destructor, or either checking that everything was stopped there. There are a lot of new code and classes in this PR, so it's worth adding more state conditions checks
| typedef bslma::ManagedPtr<bmqio::ChannelFactory::OpHandle> | ||
| ChannelFactoryOpHandleMp; | ||
|
|
||
| class ChannelFactoryPipeline : public bmqio::ChannelFactory { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bmqimp::Application::ChannelFactoryPipeline and mqbnet::TCPSessionFactory::ChannelFactoryPipeline have very similar interfaces. There are some differences though:
bmqimp::Application::ChannelFactoryPipeline: extra fieldNegotiatedChannelFactory d_negotiatedChannelFactory- fields are stored as managed pointers or direct values
Is it possible to unify interfaces, make a new component bmqio_channelfactorypipeline and reuse it from both places?
| bmqvt::ValueOrError<Certificate, Error> | ||
| loadCertificateFromPath(const bsl::string& path) BSLS_KEYWORD_OVERRIDE; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The return value type here makes us use Error that is inherited from ntsa::Error, so we expose ntf symbols and header.
There are different ways of returning results, in this header we also have this:
int loadCertificateAuthority(CertificateLoader& loader,
const bsl::string& caPath);
We can return Certificate and/or Error via pointer args. We can also return (possibly null) shared pointer to Certificate as a return value and pass output stream to log any errors, to hide ntsa::Error
| const ntca::UpgradeEvent& upgradeEvent, | ||
| const ntci::UpgradeFunction& cb) | ||
| { | ||
| BSLS_ASSERT(cb); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An interesting question if we should check this.
If cb is empty, an exception will be thrown when we try to call it a few lines below anyway. We check the same thing twice.
However, we don't do this often, it's not the data path.
| const ntci::EncryptionClient& encryptionClient() const; | ||
|
|
||
| /// @brief Access this factory's upgrade options. | ||
| const ntca::UpgradeOptions& upgradeOptions() const; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These added accessors are not used.
If we don't plan to use them, we should probably remove them to simplify the code base.
| void Tester::setEncryptionAuthority() | ||
| { | ||
| if (d_authorityCertificate && d_authorityPrivateKey) { | ||
| // Authority root has already been initialized, no need to set it again |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can also fail the test here and in other set methods in this file. If we try to set something twice it's a problem with a test design probably
| // Shorten the timeout interval | ||
| ntca::UpgradeOptions upgradeOptions; | ||
| bsls::TimeInterval deadline = bdlt::CurrentTime::now(); | ||
| // 5ms doesn't seem to interfere with the success test case, so this |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we set a bigger timeout in case we run on a slower host?
| // See the License for the specific language governing permissions and | ||
| // limitations under the License. | ||
|
|
||
| // bmqio_certificatestore.cpp -*-C++-*- |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this component still being used?
.gitignore
Outdated
| .pytest_cache/ | ||
| .cache/ | ||
| .venv/ | ||
| venv/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe not adding an extra virtual environment path to the .gitignore but rather having the user put them in .git/info/exclude if they want to
| # | ||
| # Based off of | ||
| # https://github.com/confluentinc/librdkafka/blob/master/tests/gen-ssl-certs.sh | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be great to be clear where this script is being used.
| negotiate(channel, context); | ||
| } | ||
|
|
||
| negotiationInit(channel, context); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this function be called only in else branch?
dorjesinpo
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
few questions
| // during intrusion testing) would trigger this trace. | ||
| BALL_LOG_INFO << "#TCP_UNEXPECTED_STATE " | ||
| << "TCPSessionFactory '" << d_config.name() | ||
| << "TCPSessionFactory '" << d_threadName |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the idea of changing d_config.name() to d_threadName to tell TLS from cleartext?
But d_threadName = "bmqIO_" + d_config.name().substr(0, 15 - 6);, would it look the same fro both?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Think this is an old artifact of a previous iteration, cleaning them up.
| return d_limitSignaler.connect(cb); | ||
| } | ||
|
|
||
| bdlmt::SignalerConnection NtcChannelFactory::onUpgrade(const UpgradeFn& cb) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where is onUpgrade called?
| bdlf::PlaceHolders::_2, // upgradeEvent | ||
| callback)); | ||
| if (rc != 0) { | ||
| callback(event, upgradeStatus, channel); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this not enough to inject the upgrade before calling TCPSessionFactory::channelStateCallback?
Why do we need d_upgradeSignaler?
Same for processChannelResult
2a44dc8 to
10c64a9
Compare
Added ===== - TLS configuration in broker config - Helper script for generating test certs and CAs - TLS options for NtcChannel - Loading certificates and authority data specified from bmqbrkrcfg.json - SessionOptions to bmq package for configuring client sessions - --tls-authority and --tls-version options to bmqtool to configure session options - Client sessions will now require broker TLS sessions when TLS protocol versions are specified - Create CertificateStore component for bmqio - Integration tests for TLS Changed ======= - Update ntf-core and bde dependencies Signed-off-by: Taylor Foxhall <[email protected]> Signed-off-by: Evgeny Malygin <[email protected]>
Signed-off-by: Taylor Foxhall <[email protected]>
Added
Changed