def promptPassword(self, keyDesc, prompt, promptDesc, validateCallback): try: import keyutils keyring = keyutils.KEY_SPEC_SESSION_KEYRING except ImportError: keyutils = keyring = None if keyutils: keyId = keyutils.request_key(keyDesc, keyring) if keyId is not None: passwd = keyutils.read_key(keyId) if validateCallback(passwd): return passwd # Fall through if the cached creds are invalid for x in range(3): self.write(promptDesc) passwd = self.inputPassword(prompt) if validateCallback(passwd): if keyutils: keyutils.add_key(keyDesc, passwd, keyring) return passwd if not passwd: # User wants out but getpass eats Ctrl-C break self.write("The specified credentials were not valid.\n") return None
def testLink(self): desc = b"key1" child = keyutils.add_key(b"ring1", None, keyutils.KEY_SPEC_PROCESS_KEYRING, b"keyring") parent = keyutils.add_key(b"ring2", None, keyutils.KEY_SPEC_PROCESS_KEYRING, b"keyring") keyId = keyutils.add_key(desc, b"dummy", child) self.assertEqual(keyutils.search(child, desc), keyId) self.assertEqual(keyutils.search(parent, desc), None) keyutils.link(child, parent) self.assertEqual(keyutils.search(parent, desc), keyId)
def setPassword(keyDesc, passwd): if not _keyutils: return passwd _setupSession() try: _keyutils.add_key(keyDesc, passwd, _keyring) except _keyutils.Error as err: if err.args[0] != _keyutils.EKEYREVOKED: raise # This should only happen if using old keyutils. return passwd
def memorise(self, value): assert len(value) < 16 * 1024, len(value) prevKeyId = self._keyId # Unfortunately, keyctl_update() loses the timeout associated # with the key, and in any case races any pre-existing timeout. # To avoid these complications always use add_key(). encrypted = self.__crypt.encrypt(value) keyId = keyutils.add_key(self.__keyName, encrypted, self._KeyRing.PROCESS) self._keyId = keyId keyutils.set_perm( keyId, keyutils.KEY_POS_ALL | keyutils.KEY_USR_VIEW | keyutils.KEY_USR_READ | keyutils.KEY_USR_SETATTR) self._touch() # Only add the key to the session keyring after it has # been constructed with the correct timeout to avoid # having the session keyring leak partially constructed # keys. keyutils.link(keyId, self._KeyRing.SESSION) if prevKeyId is not None: self._revoke(prevKeyId)
def testSession(self): desc = "test:key:02" val = "asdfasdfasdf" session = keyutils.join_session_keyring() keyId = keyutils.add_key(desc, val, session) self.assertEqual(keyutils.search(keyutils.KEY_SPEC_SESSION_KEYRING, desc), keyId) keyutils.join_session_keyring() self.assertEqual(keyutils.search(keyutils.KEY_SPEC_SESSION_KEYRING, desc), None)
def testSession(self): desc = b"test:key:02" val = b"asdfasdfasdf" session = keyutils.join_session_keyring() keyId = keyutils.add_key(desc, val, session) self.assertEqual(keyutils.search(keyutils.KEY_SPEC_SESSION_KEYRING, desc), keyId) keyutils.join_session_keyring() self.assertEqual(keyutils.search(keyutils.KEY_SPEC_SESSION_KEYRING, desc), None)
def testClear(self): desc = b"dummyKey" value = b"dummyValue" keyring = keyutils.KEY_SPEC_THREAD_KEYRING key_id = keyutils.add_key(desc, value, keyring) self.assertEqual(keyutils.request_key(desc, keyring), key_id) keyutils.clear(keyring) self.assertRaises(keyutils.Error, keyutils.read_key, key_id)
def testUpdate(self): desc = b"dummyKey" value = b"dummyValue1" keyring = keyutils.KEY_SPEC_THREAD_KEYRING key_id = keyutils.add_key(desc, value, keyring) self.assertEqual(b"dummyValue1", keyutils.read_key(key_id)) keyutils.update_key(key_id, b"dummyValue2") self.assertEqual(b"dummyValue2", keyutils.read_key(key_id))
def testDescribe(self): desc = b"dummyKey" value = b"dummyValue" keyring = keyutils.KEY_SPEC_THREAD_KEYRING key_id = keyutils.add_key(desc, value, keyring) ret = keyutils.describe_key(key_id) ktype, _, _, kperm, kdesc = ret.split(b';', 4) self.assertEqual(ktype, b"user") self.assertEqual(desc, kdesc)
def testSet(self): keyDesc = b"test:key:01" keyVal = b"key value with\0 some weird chars in it too" keyring = keyutils.KEY_SPEC_THREAD_KEYRING # Key not initialized; should get None keyId = keyutils.request_key(keyDesc, keyring) self.assertEqual(keyId, None) self.assertRaises(keyutils.Error, keyutils.read_key, 12345) try: keyutils.read_key(12345) except keyutils.Error as e: self.assertEqual(e.args, (126, 'Required key not available')) keyutils.add_key(keyDesc, keyVal, keyring) keyId = keyutils.request_key(keyDesc, keyring) data = keyutils.read_key(keyId) self.assertEqual(data, keyVal)
def testTimeout(self): desc = b"dummyKey" value = b"dummyValue" keyring = keyutils.KEY_SPEC_THREAD_KEYRING # create key with 1 second timeout: keyId = keyutils.add_key(desc, value, keyring) keyutils.set_timeout(keyId, 1) self.assertEqual(keyutils.request_key(desc, keyring), keyId) time.sleep(1.5) self.assertEqual(keyutils.request_key(desc, keyring), None)
def getKeyPassphrase(self, keyId, prompt, errorMessage=None): if errorMessage: print errorMessage keyDesc = "conary:pgp:%s" % keyId try: import keyutils # We only initialize keyring if keyutils is not None keyring = keyutils.KEY_SPEC_SESSION_KEYRING except ImportError: keyutils = None # If the passphrase was invalidated, we don't want to be stuck; so, if # the caller did set an error message, we will not try to use keyutils if keyutils and not errorMessage: keyId = keyutils.request_key(keyDesc, keyring) if keyId is not None: return keyutils.read_key(keyId) print print prompt passPhrase = getpass.getpass("Passphrase: ") if keyutils: keyutils.add_key(keyDesc, passPhrase, keyring) return passPhrase
def testSetPerm(self): desc = b"dummyKey" value = b"dummyValue1" keyring = keyutils.KEY_SPEC_THREAD_KEYRING key_id = keyutils.add_key(desc, value, keyring) ktype, _, _, kperm, kdesc = keyutils.describe_key(key_id).split( b';', 4) kperm = int(kperm, base=16) self.assertEqual(keyutils.KEY_POS_READ, kperm & keyutils.KEY_POS_READ) keyutils.set_perm(key_id, kperm - keyutils.KEY_POS_READ) ktype, _, _, kperm, kdesc = keyutils.describe_key(key_id).split( b';', 4) kperm = int(kperm, base=16) self.assertEqual(0, kperm & keyutils.KEY_POS_READ)
def testTimeout(self): desc = b"dummyKey" value = b"dummyValue" keyring = keyutils.KEY_SPEC_THREAD_KEYRING # create key with 1 second timeout: keyId = keyutils.add_key(desc, value, keyring) self.assertEqual(keyutils.request_key(desc, keyring), keyId) keyutils.set_timeout(keyId, 1) time.sleep(1.5) try: keyId = keyutils.request_key(desc, keyring) except keyutils.Error as err: # https://patchwork.kernel.org/patch/5336901 self.assertEqual(err.args[0], keyutils.EKEYEXPIRED) keyId = None self.assertEqual(keyId, None)
def __setitem__(self, device, value): key = self._key(device) if isinstance(value, str): value = value.encode('utf-8') key_id = keyutils.add_key(key, value, self.keyring) self._touch(key_id)
def user_set(self, key, value, pid=None): """ Sets key to value in current user's keyring. """ return _keyutils.add_key(self._format_proc_key(key, pid), value, self._user_keyring)
def get_user_password_through_keyctl(self, timeout, active_directory, skip_test, keyring=None, raise_on_error=True): ''' :param timeout: :param active_directory: :param skip_test: :param keyring: :param raise_on_error: :return: ''' password = None try: if keyring is None: # if keyring doesn't exist, generate a new keyring keyring = keyutils.KEY_SPEC_SESSION_KEYRING log.debug('KEY_SPEC_SESSION_KEYRING generated\n') elif keyring is 'user': keyring == keyutils.KEY_SPEC_USER_SESSION_KEYRING log.debug('KEY_SPEC_USER_SESSION_KEYRING generated\n') if keyring == keyutils.KEY_SPEC_SESSION_KEYRING: keyctl_keyring_name = '@s' elif keyring == keyutils.KEY_SPEC_USER_SESSION_KEYRING: keyctl_keyring_name = '@us' else: sys.exit( 'update this code to add the un translated keyring type {}\n' .format(keyring)) key_id = keyutils.request_key(self.key_name, keyring) if key_id: log.debug('Key {} exists on {}. Pulling from keyring\n'.format( self.key_name, keyring)) password = keyutils.read_key(key_id) else: log.debug( 'Key {} does not exist on {}. creating new key\n'.format( self.key_name, keyring)) password = password_check(username=self.username, keyname=self.key_name, active_directory=active_directory, skip_test=skip_test) key_id = keyutils.add_key( self.key_name, password, keyring) # for keyctl(1) the 'type' is 'user' keyutils.set_timeout(key_id, timeout) # Reset it each time it's accessed except Exception as e: if raise_on_error: raise Exception( "Failed to get key from keyutils using keyring {} - exception was {}" .format(keyctl_keyring_name, e)) return password
def __setitem__(self, device, value): key = self._key(device) key_id = keyutils.add_key(key, value.encode('utf-8'), self.keyring) self._touch(key_id)
def setPassword(keyDesc, passwd): if _keyutils: _keyutils.add_key(keyDesc, passwd, _keyring) return passwd