Authenticate using GSSAPI.
(credentials: MongoCredential, conn: AsyncConnection)
| 208 | |
| 209 | |
| 210 | async def _authenticate_gssapi(credentials: MongoCredential, conn: AsyncConnection) -> None: |
| 211 | """Authenticate using GSSAPI.""" |
| 212 | if not HAVE_KERBEROS: |
| 213 | raise ConfigurationError( |
| 214 | 'The "kerberos" module must be installed to use GSSAPI authentication.' |
| 215 | ) |
| 216 | |
| 217 | try: |
| 218 | username = credentials.username |
| 219 | password = credentials.password |
| 220 | props = credentials.mechanism_properties |
| 221 | # Starting here and continuing through the while loop below - establish |
| 222 | # the security context. See RFC 4752, Section 3.1, first paragraph. |
| 223 | host = props.service_host or conn.address[0] |
| 224 | host = await _canonicalize_hostname(host, props.canonicalize_host_name) |
| 225 | service = props.service_name + "@" + host |
| 226 | if props.service_realm is not None: |
| 227 | service = service + "@" + props.service_realm |
| 228 | |
| 229 | if password is not None: |
| 230 | if _USE_PRINCIPAL: |
| 231 | # Note that, though we use unquote_plus for unquoting URI |
| 232 | # options, we use quote here. Microsoft's UrlUnescape (used |
| 233 | # by WinKerberos) doesn't support +. |
| 234 | principal = ":".join((quote(username), quote(password))) |
| 235 | result, ctx = kerberos.authGSSClientInit( |
| 236 | service, principal, gssflags=kerberos.GSS_C_MUTUAL_FLAG |
| 237 | ) |
| 238 | else: |
| 239 | if "@" in username: |
| 240 | user, domain = username.split("@", 1) |
| 241 | else: |
| 242 | user, domain = username, None |
| 243 | result, ctx = kerberos.authGSSClientInit( |
| 244 | service, |
| 245 | gssflags=kerberos.GSS_C_MUTUAL_FLAG, |
| 246 | user=user, |
| 247 | domain=domain, |
| 248 | password=password, |
| 249 | ) |
| 250 | else: |
| 251 | result, ctx = kerberos.authGSSClientInit(service, gssflags=kerberos.GSS_C_MUTUAL_FLAG) |
| 252 | |
| 253 | if result != kerberos.AUTH_GSS_COMPLETE: |
| 254 | raise OperationFailure("Kerberos context failed to initialize.") |
| 255 | |
| 256 | try: |
| 257 | # pykerberos uses a weird mix of exceptions and return values |
| 258 | # to indicate errors. |
| 259 | # 0 == continue, 1 == complete, -1 == error |
| 260 | # Only authGSSClientStep can return 0. |
| 261 | if kerberos.authGSSClientStep(ctx, "") != 0: |
| 262 | raise OperationFailure("Unknown kerberos failure in step function.") |
| 263 | |
| 264 | # Start a SASL conversation with mongod/s |
| 265 | # Note: pykerberos deals with base64 encoded byte strings. |
| 266 | # Since mongo accepts base64 strings as the payload we don't |
| 267 | # have to use bson.binary.Binary. |
nothing calls this directly
no test coverage detected