diff --git a/lib/ansible/constants.py b/lib/ansible/constants.py index a6b77050ca..8007b36915 100644 --- a/lib/ansible/constants.py +++ b/lib/ansible/constants.py @@ -19,6 +19,7 @@ import os import pwd import sys import ConfigParser +from string import ascii_letters, digits # copied from utils, avoid circular reference fun :) def mk_boolean(value): @@ -148,6 +149,8 @@ ACCELERATE_TIMEOUT = get_config(p, 'accelerate', 'accelerate_timeout ACCELERATE_CONNECT_TIMEOUT = get_config(p, 'accelerate', 'accelerate_connect_timeout', 'ACCELERATE_CONNECT_TIMEOUT', 1.0, floating=True) PARAMIKO_PTY = get_config(p, 'paramiko_connection', 'pty', 'ANSIBLE_PARAMIKO_PTY', True, boolean=True) +# characters included in auto-generated passwords +DEFAULT_PASSWORD_CHARS = ascii_letters + digits + ".,:-_" # non-configurable things DEFAULT_SUDO_PASS = None diff --git a/lib/ansible/runner/lookup_plugins/password.py b/lib/ansible/runner/lookup_plugins/password.py index a09ca4071e..a494b694f7 100644 --- a/lib/ansible/runner/lookup_plugins/password.py +++ b/lib/ansible/runner/lookup_plugins/password.py @@ -20,7 +20,6 @@ from ansible import utils, errors import os import errno -import random from string import ascii_letters, digits @@ -33,10 +32,7 @@ class LookupModule(object): def random_salt(self): salt_chars = ascii_letters + digits + './' - salt = [] - for _ in range(8): - salt.append(random.choice(salt_chars)) - return ''.join(salt) + return utils.random_password(length=8, chars=salt_chars) def run(self, terms, inject=None, **kwargs): @@ -76,7 +72,7 @@ class LookupModule(object): if not os.path.isdir(pathdir): os.makedirs(pathdir) chars = ascii_letters + digits + ".,:-_" - password = ''.join(random.choice(chars) for _ in range(length)) + password = utils.random_password(length) if encrypt is not None: salt = self.random_salt() content = '%s salt=%s' % (password, salt) diff --git a/lib/ansible/utils/__init__.py b/lib/ansible/utils/__init__.py index 5da1322c72..c2a42ddc19 100644 --- a/lib/ansible/utils/__init__.py +++ b/lib/ansible/utils/__init__.py @@ -1006,4 +1006,13 @@ def combine_vars(a, b): else: return dict(a.items() + b.items()) +def random_password(length=20, chars=C.DEFAULT_PASSWORD_CHARS): + '''Return a random password string of length containing only chars.''' + password = [] + while len(password) < length: + new_char = os.urandom(1) + if new_char in chars: + password.append(new_char) + + return ''.join(password) diff --git a/library/cloud/linode b/library/cloud/linode index 8c71e55f65..b7d1aaa8c4 100644 --- a/library/cloud/linode +++ b/library/cloud/linode @@ -174,6 +174,8 @@ def randompass(): # we play it safe :) import random import string + # as of python 2.4, this reseeds the PRNG from urandom + random.seed() lower = ''.join(random.choice(string.ascii_lowercase) for x in range(6)) upper = ''.join(random.choice(string.ascii_uppercase) for x in range(6)) number = ''.join(random.choice(string.digits) for x in range(6))