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

auth plugin to validate client cert? #995

Open
dirkfeytons opened this issue Oct 23, 2018 · 9 comments
Open

auth plugin to validate client cert? #995

dirkfeytons opened this issue Oct 23, 2018 · 9 comments

Comments

@dirkfeytons
Copy link

I'm trying to create an auth plugin for 1.5.3 that controls client access based on their client certificate.

A first look at mosquitto_plugin.h seems to suggest this isn't possible: it only has functions to check username/password and TLS/PSK. However, reading about the config options use_identity_as_username and use_subject_as_username I was assuming that if they are used the mosquitto_auth_unpwd_check() plugin function would be called and the username can be checked (and/or the complete certificate after calling mosquitto_client_certificate()). However, this doesn't seem to work: the plugin is never invoked. (Interestingly if SIGHUP is sent to the broker it does invoke the plugin with the expected client information)

I looked a bit deeper into the code; more specifically the handle__connect() function. I think I found the reason why it's not working: if TLS is enabled and use_identity_as_username or use_subject_as_username is set, then it will parse the certificate and fill in the username. Otherwise it invokes the mosquitto_unpwd_check() function if a username is provided. That 'otherwise' seems to be the culprit. If I remove that and make a few other minor changes then the plugin is invoked.

So the question is: is my scenario supposed to work and have I found a bug, or is this an unsupported use case?

@ralight
Copy link
Contributor

ralight commented Oct 23, 2018

The use_* options are only relevant when you are using client certificates. They make the assumption that having a certificate is the authentication part and that in that situation a client doesn't actually need to provide a username. If you follow that logic but then want to use ACLs, you need some mechanism to determine when the ACL should apply - hence using subject or identity as the username. You could certainly argue that the plugin should get called anyway, I think should be the case. In fact, I think it needs reconsidering so that the plugin check is always called even if the client doesn't have a username.

For your case, not using use_*, and ensuring that the clients send a username will make the check occur.

@dirkfeytons
Copy link
Author

Thanks for the feedback.
Having a client send a (dummy) username does indeed cause the auth plugin to be invoked, but that would mean older clients are not checked by the auth plugin (and in fact we need to explicitly set allow_anonymous to true to make them still connect when an auth plugin is present).

Do you have more details on how you would ensure the plugin is always called? Introduce a new plugin function mosquitto_auth_tls_check()? Reuse the existing mosquitto_auth_unpwd_check()? I've attempted to do the latter by making some changes in handle__connect() but I've most likely done it in a wrong way or broke some scenario, and I've at least one failing test to still look into. Shall I continue anyhow and post my attempt for an initial review once the tests pass?
Any pointers are welcome...

@ralight
Copy link
Contributor

ralight commented Oct 24, 2018

My plan would be to always call mosquitto_unpwd_check() on connect. Some of the current checks in handle__connect() should really move into the default security checks, so there is a bit more consistency. Up to you if you continue or let me do it.

@ralight
Copy link
Contributor

ralight commented Oct 24, 2018

I'm happy to help you work through iterations of getting the changes made though, if that suits.

@dirkfeytons
Copy link
Author

Could you elaborate on which checks you want to move to (what I assume is) security_default.c? This is the first time I've actually looked this deep in the broker code so it will take some time to get something decent.
I'm going to try adding a test for my use case, and maybe some related ones. That's gonna be useful in any case.

@ralight
Copy link
Contributor

ralight commented Oct 25, 2018

I think roughly everything from

#ifdef WITH_TLS
to line 555 could be moved. That's just an initial guess though, some of it may require a bit of thought.

@dirkfeytons
Copy link
Author

Just a heads-up: I've added a bunch of tests that cover my scenario and made some changes to the handle__connect() function the auth plugin is always invoked. I've not attempted to split up that code because I'm not sure how to start :) I figured it would be good to first get your opinion on the current change before trying to refactor.
Currently sorting out the ECA; unfortunately no ETA on that yet...

@ralight
Copy link
Contributor

ralight commented Nov 13, 2018

Thanks for the update. If you'd like to make a pull request we can look at the code, there isn't a need for an ECA from our end until the code is ready to be accepted. I realise you might need to wait for approval before doing that though.

@LittleBobbyTable
Copy link

Hello, I'm also interested in the same behavior described here. I would like to be able to have the auth_plugin called, even so mosquitto is accepting the certificate. Since this Issue is still open I was wondering, if this found it's way in a recent version already? (Still using an older mosquitto version at the moment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants