def test_add_cred(self): target_name = gb.import_name(TARGET_SERVICE_NAME, gb.NameType.hostbased_service) client_ctx_resp = gb.init_sec_context(target_name) client_token = client_ctx_resp[3] del client_ctx_resp # free all the things (except the token)! server_name = gb.import_name(SERVICE_PRINCIPAL, gb.NameType.kerberos_principal) server_creds = gb.acquire_cred(server_name, usage='both')[0] server_ctx_resp = gb.accept_sec_context(client_token, acceptor_creds=server_creds) input_creds = gb.Creds() imp_resp = gb.add_cred(input_creds, server_ctx_resp[1], gb.MechType.kerberos) imp_resp.shouldnt_be_none() new_creds, actual_mechs, output_init_ttl, output_accept_ttl = imp_resp actual_mechs.shouldnt_be_empty() actual_mechs.should_include(gb.MechType.kerberos) output_init_ttl.should_be_a(int) output_accept_ttl.should_be_a(int) new_creds.should_be_a(gb.Creds)
def test_import_export_name_composite(self): base_name = gb.import_name(TARGET_SERVICE_NAME, gb.NameType.hostbased_service) canon_name = gb.canonicalize_name(base_name, gb.MechType.kerberos) gb.set_name_attribute(canon_name, b'urn:greet:greeting', [b'some val']) exported_name = gb.export_name_composite(canon_name) exported_name.should_be_a(bytes) # TODO(directxman12): when you just import a token as composite, # appears as this name whose text is all garbled, since it contains # all of the attributes, etc, but doesn't properly have the attributes. # Once it's canonicalized, the attributes reappear. However, if you # just import it as normal export, the attributes appear directly. # It is thus unclear as to what is going on # imported_name_raw = gb.import_name(exported_name, # gb.NameType.composite_export) # imported_name = gb.canonicalize_name(imported_name_r, # gb.MechType.kerberos) imported_name = gb.import_name(exported_name, gb.NameType.export) imported_name.should_be_a(gb.Name) get_res = gb.get_name_attribute(imported_name, b'urn:greet:greeting') get_res.values.should_be([b'some val'])
def test_import_export_name_composite_no_attrs(self): base_name = gb.import_name(TARGET_SERVICE_NAME, gb.NameType.hostbased_service) canon_name = gb.canonicalize_name(base_name, gb.MechType.kerberos) exported_name = gb.export_name_composite(canon_name) exported_name.should_be_a(bytes) imported_name = gb.import_name(exported_name, gb.NameType.composite_export) imported_name.should_be_a(gb.Name)
def test_compare_name(self): service_name1 = gb.import_name(TARGET_SERVICE_NAME) service_name2 = gb.import_name(TARGET_SERVICE_NAME) init_name = gb.import_name(self.ADMIN_PRINC, gb.NameType.kerberos_principal) gb.compare_name(service_name1, service_name2).should_be_true() gb.compare_name(service_name2, service_name1).should_be_true() gb.compare_name(service_name1, init_name).should_be_false() gb.release_name(service_name1) gb.release_name(service_name2) gb.release_name(init_name)
def setUp(self): self.target_name = gb.import_name(TARGET_SERVICE_NAME, gb.NameType.hostbased_service) ctx_resp = gb.init_sec_context(self.target_name) self.client_token = ctx_resp[3] self.client_ctx = ctx_resp[0] self.client_ctx.shouldnt_be_none() self.server_name = gb.import_name(SERVICE_PRINCIPAL, gb.NameType.kerberos_principal) self.server_creds = gb.acquire_cred(self.server_name)[0] self.server_ctx = None
def test_inquire_mechs_for_name(self): name = gb.import_name(self.USER_PRINC, gb.NameType.kerberos_principal) res = gb.inquire_mechs_for_name(name) res.shouldnt_be_none() res.should_include(gb.MechType.kerberos)
def test_import_name(self): imported_name = gb.import_name(TARGET_SERVICE_NAME) imported_name.shouldnt_be_none() imported_name.should_be_a(gb.Name) gb.release_name(imported_name)
def authenticate(self, request, username=None, password=None, **kwargs): '''Verify username and password using Kerberos''' warnings.warn('Kerberos: example backend do not use in production!') # pylint: disable=invalid-name User = get_user_model() if username is None: username = kwargs.get(User.USERNAME_FIELD) try: user = User._default_manager.get_by_natural_key(username) except User.DoesNotExist: logger.debug('Kerberos: no user for username %s', username) return None else: if not user.is_active: return None principal = self.principal_from_user(user) name = gb.import_name(force_bytes(principal), gb.NameType.kerberos_principal) try: gb.acquire_cred_with_password(name, force_bytes(password)) except gssapi.exceptions.GSSError as e: logger.debug( 'Kerberos: password check failed for principal %s: %s', principal, e) return None if not user.check_password(password): user.set_password(password) user.save() return user
def test_store_cred_into_acquire_cred(self): CCACHE = 'FILE:{tmpdir}/other_ccache'.format(tmpdir=self.realm.tmpdir) KT = '{tmpdir}/other_keytab'.format(tmpdir=self.realm.tmpdir) store = { b'ccache': CCACHE.encode('UTF-8'), b'keytab': KT.encode('UTF-8') } princ_name = 'service/cs@' + self.realm.realm self.realm.addprinc(princ_name) self.realm.extract_keytab(princ_name, KT) self.realm.kinit(princ_name, None, ['-k', '-t', KT]) initial_creds = gb.acquire_cred(None, usage='initiate').creds # NB(sross): overwrite because the ccache doesn't exist yet store_res = gb.store_cred_into(store, initial_creds, overwrite=True) store_res.mechs.shouldnt_be_none() store_res.usage.should_be('initiate') name = gb.import_name(princ_name.encode('UTF-8')) retrieve_res = gb.acquire_cred_from(store, name) retrieve_res.shouldnt_be_none() retrieve_res.creds.shouldnt_be_none() retrieve_res.creds.should_be_a(gb.Creds) retrieve_res.mechs.shouldnt_be_empty() retrieve_res.mechs.should_include(gb.MechType.kerberos) retrieve_res.lifetime.should_be_an_integer()
def test_store_cred_acquire_cred(self): # we need to acquire a forwardable ticket svc_princ = SERVICE_PRINCIPAL.decode("UTF-8") self.realm.kinit(svc_princ, flags=['-k', '-f']) target_name = gb.import_name(TARGET_SERVICE_NAME, gb.NameType.hostbased_service) client_creds = gb.acquire_cred(None, usage='initiate').creds client_ctx_resp = gb.init_sec_context( target_name, creds=client_creds, flags=gb.RequirementFlag.delegate_to_peer) client_token = client_ctx_resp[3] server_creds = gb.acquire_cred(None, usage='accept').creds server_ctx_resp = gb.accept_sec_context(client_token, acceptor_creds=server_creds) deleg_creds = server_ctx_resp.delegated_creds deleg_creds.shouldnt_be_none() store_res = gb.store_cred(deleg_creds, usage='initiate', set_default=True, overwrite=True) store_res.shouldnt_be_none() store_res.usage.should_be('initiate') store_res.mechs.should_include(gb.MechType.kerberos) deleg_name = gb.inquire_cred(deleg_creds).name acq_resp = gb.acquire_cred(deleg_name, usage='initiate') acq_resp.shouldnt_be_none()
def test_store_cred_into_acquire_cred(self): CCACHE = 'FILE:{tmpdir}/other_ccache'.format(tmpdir=self.realm.tmpdir) KT = '{tmpdir}/other_keytab'.format(tmpdir=self.realm.tmpdir) store = {b'ccache': CCACHE.encode('UTF-8'), b'keytab': KT.encode('UTF-8')} princ_name = 'service/cs@' + self.realm.realm self.realm.addprinc(princ_name) self.realm.extract_keytab(princ_name, KT) self.realm.kinit(princ_name, None, ['-k', '-t', KT]) initial_creds = gb.acquire_cred(None, usage='initiate').creds # NB(sross): overwrite because the ccache doesn't exist yet store_res = gb.store_cred_into(store, initial_creds, overwrite=True) store_res.mechs.shouldnt_be_none() store_res.usage.should_be('initiate') name = gb.import_name(princ_name.encode('UTF-8')) retrieve_res = gb.acquire_cred_from(store, name) retrieve_res.shouldnt_be_none() retrieve_res.creds.shouldnt_be_none() retrieve_res.creds.should_be_a(gb.Creds) retrieve_res.mechs.shouldnt_be_empty() retrieve_res.mechs.should_include(gb.MechType.kerberos) retrieve_res.lifetime.should_be_an_integer()
def test_store_cred_acquire_cred(self): # we need to acquire a forwardable ticket svc_princ = SERVICE_PRINCIPAL.decode("UTF-8") self.realm.kinit(svc_princ, flags=['-k', '-f']) target_name = gb.import_name(TARGET_SERVICE_NAME, gb.NameType.hostbased_service) client_creds = gb.acquire_cred(None, usage='initiate').creds client_ctx_resp = gb.init_sec_context( target_name, creds=client_creds, flags=gb.RequirementFlag.delegate_to_peer) client_token = client_ctx_resp[3] server_creds = gb.acquire_cred(None, usage='accept').creds server_ctx_resp = gb.accept_sec_context(client_token, acceptor_creds=server_creds) deleg_creds = server_ctx_resp.delegated_creds deleg_creds.shouldnt_be_none() store_res = gb.store_cred(deleg_creds, usage='initiate', set_default=True) store_res.shouldnt_be_none() store_res.usage.should_be('initiate') store_res.mechs.should_include(gb.MechType.kerberos) deleg_name = gb.inquire_cred(deleg_creds).name acq_resp = gb.acquire_cred(deleg_name, usage='initiate') acq_resp.shouldnt_be_none()
def test_inquire_context(self): target_name = gb.import_name(TARGET_SERVICE_NAME, gb.NameType.hostbased_service) ctx_resp = gb.init_sec_context(target_name) client_token1 = ctx_resp[3] client_ctx = ctx_resp[0] server_name = gb.import_name(SERVICE_PRINCIPAL, gb.NameType.kerberos_principal) server_creds = gb.acquire_cred(server_name)[0] server_resp = gb.accept_sec_context(client_token1, acceptor_creds=server_creds) server_tok = server_resp[3] client_resp2 = gb.init_sec_context(target_name, context=client_ctx, input_token=server_tok) ctx = client_resp2[0] inq_resp = gb.inquire_context(ctx) inq_resp.shouldnt_be_none() (src_name, target_name, ttl, mech_type, flags, local_est, is_open) = inq_resp src_name.shouldnt_be_none() src_name.should_be_a(gb.Name) target_name.shouldnt_be_none() target_name.should_be_a(gb.Name) ttl.should_be_an_integer() mech_type.shouldnt_be_none() mech_type.should_be(gb.MechType.kerberos) flags.shouldnt_be_none() flags.should_be_a(collections.Set) flags.shouldnt_be_empty() local_est.should_be_a(bool) local_est.should_be_true() is_open.should_be_a(bool) is_open.should_be_true()
def test_inquire_name_not_mech_name(self): base_name = gb.import_name(TARGET_SERVICE_NAME, gb.NameType.hostbased_service) inquire_res = gb.inquire_name(base_name) inquire_res.shouldnt_be_none() inquire_res.is_mech_name.should_be_false() inquire_res.mech.should_be_none()
def setUp(self): self.target_name = gb.import_name(TARGET_SERVICE_NAME, gb.NameType.hostbased_service) ctx_resp = gb.init_sec_context(self.target_name) self.client_token1 = ctx_resp[3] self.client_ctx = ctx_resp[0] self.server_name = gb.import_name(SERVICE_PRINCIPAL, gb.NameType.kerberos_principal) self.server_creds = gb.acquire_cred(self.server_name)[0] server_resp = gb.accept_sec_context(self.client_token1, acceptor_creds=self.server_creds) self.server_ctx = server_resp[0] self.server_tok = server_resp[3] client_resp2 = gb.init_sec_context(self.target_name, context=self.client_ctx, input_token=self.server_tok) self.client_token2 = client_resp2[3] self.client_ctx = client_resp2[0]
def test_inquire_name_mech_name(self): base_name = gb.import_name(TARGET_SERVICE_NAME, gb.NameType.hostbased_service) mech_name = gb.canonicalize_name(base_name, gb.MechType.kerberos) inquire_res = gb.inquire_name(mech_name) inquire_res.shouldnt_be_none() inquire_res.is_mech_name.should_be_true() inquire_res.mech.should_be_a(gb.OID) inquire_res.mech.should_be(gb.MechType.kerberos)
def test_inquire_name_with_attrs(self): base_name = gb.import_name(TARGET_SERVICE_NAME, gb.NameType.hostbased_service) canon_name = gb.canonicalize_name(base_name, gb.MechType.kerberos) gb.set_name_attribute(canon_name, b'urn:greet:greeting', [b'some greeting']) inquire_res = gb.inquire_name(canon_name) inquire_res.shouldnt_be_none() inquire_res.attrs.should_be_a(list) inquire_res.attrs.should_be([b'urn:greet:greeting'])
def test_context_time(self): target_name = gb.import_name(TARGET_SERVICE_NAME, gb.NameType.hostbased_service) ctx_resp = gb.init_sec_context(target_name) client_token1 = ctx_resp[3] client_ctx = ctx_resp[0] server_name = gb.import_name(SERVICE_PRINCIPAL, gb.NameType.kerberos_principal) server_creds = gb.acquire_cred(server_name)[0] server_resp = gb.accept_sec_context(client_token1, acceptor_creds=server_creds) server_tok = server_resp[3] client_resp2 = gb.init_sec_context(target_name, context=client_ctx, input_token=server_tok) ctx = client_resp2[0] ttl = gb.context_time(ctx) ttl.should_be_an_integer() ttl.should_be_greater_than(0)
def test_bad_channel_binding_raises_error(self): bdgs = gb.ChannelBindings(application_data=b'abcxyz', initiator_address_type=gb.AddressType.ip, initiator_address=b'127.0.0.1', acceptor_address_type=gb.AddressType.ip, acceptor_address=b'127.0.0.1') self.target_name = gb.import_name(TARGET_SERVICE_NAME, gb.NameType.hostbased_service) ctx_resp = gb.init_sec_context(self.target_name, channel_bindings=bdgs) self.client_token = ctx_resp[3] self.client_ctx = ctx_resp[0] self.client_ctx.shouldnt_be_none() self.server_name = gb.import_name(SERVICE_PRINCIPAL, gb.NameType.kerberos_principal) self.server_creds = gb.acquire_cred(self.server_name)[0] bdgs.acceptor_address = b'127.0.1.0' gb.accept_sec_context.should_raise(gb.GSSError, self.client_token, acceptor_creds=self.server_creds, channel_bindings=bdgs)
def test_display_name(self): imported_name = gb.import_name(TARGET_SERVICE_NAME, gb.NameType.hostbased_service) displ_resp = gb.display_name(imported_name) displ_resp.shouldnt_be_none() (displayed_name, out_type) = displ_resp displayed_name.shouldnt_be_none() displayed_name.should_be_a(bytes) displayed_name.should_be(TARGET_SERVICE_NAME) out_type.shouldnt_be_none() out_type.should_be(gb.NameType.hostbased_service)
def test_canonicalize_export_name(self): imported_name = gb.import_name(self.ADMIN_PRINC, gb.NameType.kerberos_principal) canonicalized_name = gb.canonicalize_name(imported_name, gb.MechType.kerberos) canonicalized_name.shouldnt_be_none() canonicalized_name.should_be_a(gb.Name) exported_name = gb.export_name(canonicalized_name) exported_name.shouldnt_be_none() exported_name.should_be_a(bytes) exported_name.shouldnt_be_empty()
def test_inquire_creds(self): name = gb.import_name(SERVICE_PRINCIPAL, gb.NameType.kerberos_principal) cred = gb.acquire_cred(name).creds inq_resp = gb.inquire_cred(cred) inq_resp.shouldnt_be_none() inq_resp.name.should_be_a(gb.Name) assert gb.compare_name(name, inq_resp.name) inq_resp.lifetime.should_be_an_integer() inq_resp.usage.should_be('both') inq_resp.mechs.shouldnt_be_empty() inq_resp.mechs.should_include(gb.MechType.kerberos)
def test_always_get_delegated_creds(self): svc_princ = SERVICE_PRINCIPAL.decode("UTF-8") self.realm.kinit(svc_princ, flags=['-k', '-f']) target_name = gb.import_name(TARGET_SERVICE_NAME, gb.NameType.hostbased_service) client_token = gb.init_sec_context(target_name).token # if our acceptor creds have a usage of both, we get # s4u2proxy delegated credentials server_creds = gb.acquire_cred(None, usage='both').creds server_ctx_resp = gb.accept_sec_context(client_token, acceptor_creds=server_creds) server_ctx_resp.shouldnt_be_none() server_ctx_resp.delegated_creds.shouldnt_be_none() server_ctx_resp.delegated_creds.should_be_a(gb.Creds)
def test_acquire_creds(self): name = gb.import_name(SERVICE_PRINCIPAL, gb.NameType.kerberos_principal) cred_resp = gb.acquire_cred(name) cred_resp.shouldnt_be_none() (creds, actual_mechs, ttl) = cred_resp creds.shouldnt_be_none() creds.should_be_a(gb.Creds) actual_mechs.shouldnt_be_empty() actual_mechs.should_include(gb.MechType.kerberos) ttl.should_be_an_integer() gb.release_name(name) gb.release_cred(creds)
def test_acquire_cred_with_password(self): password = self.realm.password('user') self.realm.kinit(self.realm.user_princ, password=password) name = gb.import_name(b'user', gb.NameType.kerberos_principal) imp_resp = gb.acquire_cred_with_password(name, password.encode('UTF-8')) imp_resp.shouldnt_be_none() imp_creds, actual_mechs, output_ttl = imp_resp imp_creds.shouldnt_be_none() imp_creds.should_be_a(gb.Creds) actual_mechs.shouldnt_be_empty() actual_mechs.should_include(gb.MechType.kerberos) output_ttl.should_be_a(int)
def test_basic_get_set_delete_name_attributes_no_auth(self): base_name = gb.import_name(TARGET_SERVICE_NAME, gb.NameType.hostbased_service) canon_name = gb.canonicalize_name(base_name, gb.MechType.kerberos) gb.set_name_attribute(canon_name, b'urn:greet:greeting', [b'some other val'], complete=True) get_res = gb.get_name_attribute(canon_name, b'urn:greet:greeting') get_res.shouldnt_be_none() get_res.values.should_be_a(list) get_res.values.should_be([b'some other val']) get_res.display_values.should_be_a(list) get_res.display_values.should_be(get_res.values) get_res.complete.should_be_true() get_res.authenticated.should_be_false() gb.delete_name_attribute(canon_name, b'urn:greet:greeting')
def test_create_from_other(self): raw_name = gb.import_name(SERVICE_PRINCIPAL) high_level_name = gssnames.Name(raw_name) bytes(high_level_name).should_be(SERVICE_PRINCIPAL)
def test_duplicate_name(self): orig_name = gb.import_name(TARGET_SERVICE_NAME) new_name = gb.duplicate_name(orig_name) new_name.shouldnt_be_none() gb.compare_name(orig_name, new_name).should_be_true()
def setUp(self): self.target_name = gb.import_name(TARGET_SERVICE_NAME, gb.NameType.hostbased_service)
def test_create_from_other(self): raw_name = gb.import_name(SERVICE_PRINCIPAL) high_level_name = gssnames.Name(raw_name) self.assertEqual(bytes(high_level_name), SERVICE_PRINCIPAL)