Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

password lookup argument parsing fix #78080

Merged
merged 8 commits into from Jun 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions changelogs/fragments/password_lookup_fix.yml
@@ -0,0 +1,2 @@
bugfixes:
- password lookup does not ignore k=v arguments anymore.
18 changes: 10 additions & 8 deletions lib/ansible/plugins/lookup/password.py
Expand Up @@ -124,7 +124,6 @@
import os
import string
import time
import shutil
import hashlib

from ansible.errors import AnsibleError, AnsibleAssertionError
Expand All @@ -139,12 +138,15 @@
VALID_PARAMS = frozenset(('length', 'encrypt', 'chars', 'ident', 'seed'))


def _parse_parameters(term):
def _parse_parameters(term, kwargs=None):
"""Hacky parsing of params

See https://github.com/ansible/ansible-modules-core/issues/1968#issuecomment-136842156
and the first_found lookup For how we want to fix this later
"""
if kwargs is None:
kwargs = {}

first_split = term.split(' ', 1)
if len(first_split) <= 1:
# Only a single argument given, therefore it's a path
Expand Down Expand Up @@ -172,12 +174,12 @@ def _parse_parameters(term):
raise AnsibleError('Unrecognized parameter(s) given to password lookup: %s' % ', '.join(invalid_params))

# Set defaults
params['length'] = int(params.get('length', DEFAULT_LENGTH))
params['encrypt'] = params.get('encrypt', None)
params['ident'] = params.get('ident', None)
params['seed'] = params.get('seed', None)
params['length'] = int(params.get('length', kwargs.get('length', DEFAULT_LENGTH)))
params['encrypt'] = params.get('encrypt', kwargs.get('encrypt', None))
params['ident'] = params.get('ident', kwargs.get('ident', None))
params['seed'] = params.get('seed', kwargs.get('seed', None))

params['chars'] = params.get('chars', None)
params['chars'] = params.get('chars', kwargs.get('chars', None))
if params['chars']:
tmp_chars = []
if u',,' in params['chars']:
Expand Down Expand Up @@ -338,7 +340,7 @@ def run(self, terms, variables, **kwargs):
ret = []

for term in terms:
relpath, params = _parse_parameters(term)
relpath, params = _parse_parameters(term, kwargs)
path = self._loader.path_dwim(relpath)
b_path = to_bytes(path, errors='surrogate_or_strict')
chars = _gen_candidate_chars(params['chars'])
Expand Down
45 changes: 45 additions & 0 deletions test/integration/targets/lookup_password/tasks/main.yml
Expand Up @@ -102,3 +102,48 @@
assert:
that:
- "newpass != newpass2"

- name: test both types of args and that seed guarantees same results
vars:
pns: "{{passwords_noseed['results']}}"
inl: "{{passwords_inline['results']}}"
kv: "{{passwords['results']}}"
l: [1, 2, 3]
block:
- name: generate passwords w/o seed
debug:
msg: '{{ lookup("password", "/dev/null")}}'
loop: "{{ l }}"
register: passwords_noseed

- name: verify they are all different, this is not guaranteed, but statisically almost impossible
assert:
that:
- pns[0]['msg'] != pns[1]['msg']
- pns[0]['msg'] != pns[2]['msg']
- pns[1]['msg'] != pns[2]['msg']

- name: generate passwords, with seed inline
debug:
msg: '{{ lookup("password", "/dev/null seed=foo")}}'
loop: "{{ l }}"
register: passwords_inline

- name: verify they are all the same
assert:
that:
- inl[0]['msg'] == inl[1]['msg']
- inl[0]['msg'] == inl[2]['msg']

- name: generate passwords, with seed k=v
debug:
msg: '{{ lookup("password", "/dev/null", seed="foo")}}'
loop: "{{ l }}"
register: passwords

- name: verify they are all the same
assert:
that:
- kv[0]['msg'] == kv[1]['msg']
- kv[0]['msg'] == kv[2]['msg']
- kv[0]['msg'] == inl[0]['msg']