-
Notifications
You must be signed in to change notification settings - Fork 181
RUST-2235 Implement GSSAPI auth support #1413
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
@@ -67,8 +69,7 @@ pub enum AuthMechanism { | |||
/// Kerberos authentication mechanism as defined in [RFC 4752](http://tools.ietf.org/html/rfc4752). | |||
/// | |||
/// See the [MongoDB documentation](https://www.mongodb.com/docs/manual/core/kerberos/) for more information. | |||
/// | |||
/// Note: This mechanism is not currently supported by this driver but will be in the future. | |||
#[cfg(feature = "gssapi-auth")] |
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.
I followed the same pattern as the aws-auth
feature flag.
// Limit number of auth challenge steps (typically, only one step is needed, however | ||
// different configurations may require more). | ||
for _ in 0..10 { |
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.
This idea is taken directly from the python driver's implementation (link).
It seems there may be some circumstances where multiple challenges need to be stepped through, so we need to do this multiple times. However, based on the python implementation's comments, it seems there may be protocol and/or library issues that could result in endless looping so a limit is put in place (10 tries).
impl GssapiProperties { | ||
pub fn from_credential(credential: &Credential) -> Result<Self> { | ||
let mut properties = GssapiProperties { | ||
service_name: "mongodb".to_string(), |
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.
You may notice that in options.rs
, we also ensure that mongodb
is the default service name. That is required in options.rs
for spec compliance (as in, the spec tests cannot pass without doing that). At this point, although we know mechanism_properites.get(SERVICE_NAME)
must always return Some(...)
, it felt cleanest to me to implement this code the way you see here (including "mongodb"
as a default value).
} else if let Some(user_principal) = user_principal.as_ref() { | ||
if let Some(idx) = user_principal.find('@') { | ||
// If no SERVICE_REALM was specified, use realm specified in the | ||
// username. Note that `realm` starts with '@'. | ||
let (_, realm) = user_principal.split_at(idx); | ||
service_principal = format!("{}{}", service_principal, realm); | ||
} | ||
} |
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.
This is not mentioned in the spec but it did end up being required since there is no other way to specify a realm for the service principal if not done manually. Perhaps other language libraries default to this behavior, but not cross-krb5
/libgssapi
in Rust. I spoke to James about this and he said he had to do something similar in the C# driver's GSSAPI implementation.
} | ||
} | ||
|
||
fn canonicalize_hostname(hostname: &str, mode: &CanonicalizeHostName) -> Result<String> { |
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.
I wrote some unit tests for this but ultimately removed them since they are trivial. The more interesting testing of this will be indirect via the end-to-end GSSAPI auth tests in the next ticket.
@abr-egn I am not able to add other reviewers, so if you know who else could/should be tagged on this, can you add them? Thank you! |
Assigned |
Ok I believe I've addressed the majority of failures now. The two remaining issues are:
Beyond addressing those two issues, the last thing I need to do is double check the spec for how to handle password being provided on Windows. It looks like there is supposed to be some special handling that happens only on Windows if the password is provided as a uri option. I'll look into that and make any relevant changes. |
This PR implements the GSSAPI auth mechanism, as described by the spec. This took a bit longer than anticipated because manual end-to-end testing revealed that the initial implementation was not correct. Subsequent fixes made slow progress towards correctness. Ultimately, the implementation you see here has been manually tested on macOS (locally, against a local KDC and mongod) and an ubuntu2204-arm64-small evergreen host (against the LDAPTEST KDC/mongod). I still need to test this on Windows. I have a separate follow-up ticket to implement automated end-to-end testing, RUST-2236, which I will put up a PR for after confirming this works on Windows and actually writing end-to-end tests.
This implementation is guarded by a feature flag, and passes the existing spec tests when the feature flag is enabled.