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