def _random_salt(): """Return a text string suitable for use as a salt for the hash functions we use to encrypt passwords. """ # Note passlib salt values must be pure ascii so we can't let the user # configure this salt_chars = _gen_candidate_chars(['ascii_letters', 'digits', './']) return random_password(length=8, chars=salt_chars)
def type5_pw(password, salt=None): if not HAS_PASSLIB: raise AnsibleFilterError( 'type5_pw filter requires PassLib library to be installed') if not isinstance(password, string_types): raise AnsibleFilterError( "type5_pw password input should be a string, but was given a input of %s" % (type(password).__name__)) salt_chars = ansible_password._gen_candidate_chars( ['ascii_letters', 'digits', './']) if salt is not None and not isinstance(salt, string_types): raise AnsibleFilterError( "type5_pw salt input should be a string, but was given a input of %s" % (type(salt).__name__)) elif not salt: salt = random_password(length=4, chars=salt_chars) elif not set(salt) <= set(salt_chars): raise AnsibleFilterError( "type5_pw salt used inproper characters, must be one of %s" % (salt_chars)) encrypted_password = md5_crypt.encrypt(password, salt=salt) return encrypted_password
def run(self, terms, variables, **kwargs): ret = [] for term in terms: relpath, params = _parse_parameters(term) path = self._loader.path_dwim(relpath) b_path = to_bytes(path, errors='surrogate_or_strict') chars = _gen_candidate_chars(params['chars']) changed = False content = _read_password_file(b_path) if content is None or b_path == to_bytes('/dev/null'): plaintext_password = random_password(params['length'], chars) salt = None changed = True else: plaintext_password, salt = _parse_content(content) if params['encrypt'] and not salt: changed = True salt = _random_salt() if changed and b_path != to_bytes('/dev/null'): content = _format_content(plaintext_password, salt, encrypt=params['encrypt']) _write_password_file(b_path, content) if params['encrypt']: password = do_encrypt(plaintext_password, params['encrypt'], salt=salt) ret.append(password) else: ret.append(plaintext_password) return ret
def run(self, terms, variables, **kwargs): ret = [] for term in terms: relpath, params = _parse_parameters(term) path = self._loader.path_dwim(relpath) b_path = to_bytes(path, errors='surrogate_or_strict') chars = _gen_candidate_chars(params['chars']) changed = None # make sure only one process finishes all the job first first_process, lockfile = _get_lock(b_path) content = _read_password_file(b_path) if content is None or b_path == to_bytes('/dev/null'): plaintext_password = random_password(params['length'], chars, params['seed']) salt = None changed = True else: plaintext_password, salt = _parse_content(content) encrypt = params['encrypt'] if encrypt and not salt: changed = True try: salt = random_salt(BaseHash.algorithms[encrypt].salt_size) except KeyError: salt = random_salt() ident = params['ident'] if encrypt and not ident: changed = True try: ident = BaseHash.algorithms[encrypt].implicit_ident except KeyError: ident = None if changed and b_path != to_bytes('/dev/null'): content = _format_content(plaintext_password, salt, encrypt=encrypt, ident=ident) _write_password_file(b_path, content) if first_process: # let other processes continue _release_lock(lockfile) if encrypt: password = do_encrypt(plaintext_password, encrypt, salt=salt, ident=ident) ret.append(password) else: ret.append(plaintext_password) return ret
def type5_pw(password, salt=None): if not isinstance(password, string_types): raise AnsibleFilterError( "type5_pw password input should be a string, but was given a input of %s" % (type(password).__name__) ) salt_chars = "".join( (to_text(string.ascii_letters), to_text(string.digits), "./") ) if salt is not None and not isinstance(salt, string_types): raise AnsibleFilterError( "type5_pw salt input should be a string, but was given a input of %s" % (type(salt).__name__) ) elif not salt: salt = random_password(length=4, chars=salt_chars) elif not set(salt) <= set(salt_chars): raise AnsibleFilterError( "type5_pw salt used inproper characters, must be one of %s" % (salt_chars) ) encrypted_password = passlib_or_crypt(password, "md5_crypt", salt=salt) return encrypted_password
def get_newpass(self): if self.paramvals['nosymbols']: chars = C.DEFAULT_PASSWORD_CHARS[:62] else: chars = C.DEFAULT_PASSWORD_CHARS if self.paramvals['userpass']: newpass = self.paramvals['userpass'] else: newpass = random_password(length=self.paramvals['length'], chars=chars) return newpass
def run(self, terms, variables, **kwargs): ret = [] for term in terms: relpath, params = _parse_parameters(term) path = self._loader.path_dwim(relpath) b_path = to_bytes(path, errors='surrogate_or_strict') chars = _gen_candidate_chars(params['chars']) changed = None # make sure only one process finishes all the job first first_process, lockfile = _get_lock(b_path) content = _read_password_file(b_path) if content is None or b_path == to_bytes('/dev/null'): plaintext_password = random_password(params['length'], chars) salt = None changed = True else: plaintext_password, salt = _parse_content(content) if params['encrypt'] and not salt: changed = True salt = random_salt() if changed and b_path != to_bytes('/dev/null'): content = _format_content(plaintext_password, salt, encrypt=params['encrypt']) _write_password_file(b_path, content) if first_process: # let other processes continue _release_lock(lockfile) if params['encrypt']: password = do_encrypt(plaintext_password, params['encrypt'], salt=salt) ret.append(password) else: ret.append(plaintext_password) return ret
def run(self, terms, variables, **kwargs): ret = [] for term in terms: relpath, params = _parse_parameters(term) path = self._loader.path_dwim(relpath) b_path = to_bytes(path, errors='surrogate_or_strict') chars = _gen_candidate_chars(params['chars']) changed = False content = _read_password_file(b_path) if content is None or b_path == to_bytes('/dev/null'): for attempts in range(10): plaintext_password = random_password(params['length'], chars) if _check_complexity(params['chars'], plaintext_password): break else: print("trying again!!!") plaintext_password = None if plaintext_password is None: raise AnsibleError( 'Unuable to generate password of sufficient complexity in 10 tries') salt = None changed = True else: plaintext_password, salt = _parse_content(content) if params['encrypt'] and not salt: changed = True salt = _random_salt() if changed and b_path != to_bytes('/dev/null'): content = _format_content(plaintext_password, salt, encrypt=params['encrypt']) _write_password_file(b_path, content) if params['encrypt']: password = do_encrypt(plaintext_password, params['encrypt'], salt=salt) ret.append(password) else: ret.append(plaintext_password) return ret
def run(self, tmp=None, task_vars=None): result = super(ActionModule, self).run(tmp, task_vars) if not HAVE_CRYPTOGRAPHY: raise AnsibleActionFail('the cryptography module is not installed') key = self._task.args.get('key', task_vars['password_key']) name = self._task.args.get('name') state = self._task.args.get('state', 'present') directory = self._task.args.get('directory', task_vars['password_directory']) length = int(self._task.args.get('length', 16)) # E: Key material must be bytes key = to_bytes(key) # params['chars'] = params.get('chars', None) # if params['chars']: # tmp_chars = [] # if u',,' in params['chars']: # tmp_chars.append(u',') # tmp_chars.extend(c for c in params['chars'].replace(u',,', u',').split(u',') if c) # params['chars'] = tmp_chars # else: # # Default chars for password # params['chars'] = [u'ascii_letters', u'digits', u".,:-_"] # chars = self._task.args.get('chars', 'ascii_letters,digits') chars = _gen_candidate_chars([u'ascii_letters', u'digits', u".,:-_"]) path = os.path.join(directory, name) if state == 'present': if self._pwd_entry_exists(path, task_vars): salt, ciphertext = self._pwd_entry_get(path, task_vars) cleartext = self.decrypt(key, salt, ciphertext) result['changed'] = False result['value'] = cleartext else: cleartext = random_password(length=length, chars=chars) salt, ciphertext = self.encrypt(key, cleartext) if not self._play_context.check_mode: self._mkdirs(directory, task_vars) self._pwd_entry_set(path, salt, ciphertext, task_vars) result['changed'] = True result['value'] = cleartext elif state == 'absent': if self._pwd_entry_exists(path, task_vars): if not self._play_context.check_mode: self._pwd_entry_remove(path, task_vars) result['changed'] = True else: result['changed'] = False return result
def get_newpass(self): if self.paramvals['userpass']: newpass = self.paramvals['userpass'] else: newpass = random_password(length=self.paramvals['length']) return newpass
def merge_with_database(base, database, app_name, customer, environment): """ Merge a database information with a database structure already existent. If database already exist the new one is ignored. """ if not isinstance(base, dict) or not isinstance(database, dict): raise AnsibleFilterError("input database is empty") if not isinstance(environment, dict): raise AnsibleFilterError("input environment must be a dictionnary") if "engine" not in database: raise AnsibleFilterError( "input database should define an 'engine' key") if "release" not in database: raise AnsibleFilterError( "input database should define a 'release' key") if "code" not in environment: raise AnsibleFilterError("environment dict should define a 'code' key") if "name" not in environment: raise AnsibleFilterError("environment dict should define a 'name' key") result = deepcopy(base) database_name = "_".join([environment.get("code"), customer, app_name]) new_database = { "application": app_name, "password": random_password(), "name": database_name, "user": database_name, } engine = database.get("engine") if engine not in result: # Create a new entry for this database engine result[database.get("engine")] = [{ "release": database.get("release"), "databases": [new_database] }] return result # Loop over defined engines and look for existing releases for defined_engine in result[engine]: if defined_engine.get("release", None) == database.get("release"): # Target release already exists for defined_database in defined_engine.get("databases"): if defined_database.get("application") == app_name: # Target database already exist: abort break else: # Add a new entry for targeted database engine and release defined_engine.get("databases").append(new_database) else: # Add a new release and database for targeted database engine result[engine].append({ "release": database.get("release"), "databases": [new_database] }) return result