예제 #1
0
def test_do_encrypt_no_passlib():
    with passlib_off():
        assert not encrypt.PASSLIB_AVAILABLE
        assert encrypt.do_encrypt("123", "md5_crypt", salt="12345678") == "$1$12345678$tRy4cXc3kmcfRZVj4iFXr/"

        with pytest.raises(AnsibleError):
            encrypt.do_encrypt("123", "crypt16", salt="12")
예제 #2
0
def test_do_encrypt_passlib():
    if not encrypt.PASSLIB_AVAILABLE:
        pytest.skip("passlib not available")

    with pytest.raises(AnsibleError):
        encrypt.do_encrypt("123", "sha257_crypt", salt="12345678")

    # Uses 5000 rounds by default for sha256 matching crypt behaviour.
    assert encrypt.do_encrypt("123", "sha256_crypt", salt="12345678") == "$5$12345678$uAZsE3BenI2G.nA8DpTl.9Dc8JiqacI53pEqRr5ppT7"

    assert encrypt.do_encrypt("123", "md5_crypt", salt="12345678") == "$1$12345678$tRy4cXc3kmcfRZVj4iFXr/"

    assert encrypt.do_encrypt("123", "crypt16", salt="12") == "12pELHK2ME3McUFlHxel6uMM"
예제 #3
0
    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 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
예제 #5
0
    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
예제 #6
0
 def do_test(name, password, hashed=None, salt=None):
     if not hashed:
         kwargs = {'salt': salt} if salt else {}
         hashed = do_encrypt(password, digest.name, **kwargs)
     ok = digest.verify(password, hashed)
     tests[name] = results(hashed, ok)
     tests['ok'][name] = ok
예제 #7
0
 def do_test(name, password, hashed=None, salt=None):
     if not hashed:
         kwargs = {'salt': salt} if salt else {}
         hashed = do_encrypt(password, digest.name, **kwargs)
     ok = digest.verify(password, hashed)
     tests[name] = results(hashed, ok)
     tests['ok'][name] = ok
예제 #8
0
    def run(self, terms, variables, **kwargs):

        ret = []

        for term in terms:
            relpath, params = _parse_parameters(term)

            # get password or create it if file doesn't exist
            path = self._loader.path_dwim(relpath)
            if not os.path.exists(path):
                pathdir = os.path.dirname(path)
                try:
                    makedirs_safe(pathdir, mode=0o700)
                except OSError as e:
                    raise AnsibleError("cannot create the path for the password lookup: %s (error was %s)" % (pathdir, str(e)))

                chars = "".join(getattr(string, c, c) for c in params['chars']).replace('"', '').replace("'", '')
                password = ''.join(random.choice(chars) for _ in range(params['length']))

                if params['encrypt'] is not None:
                    salt = self.random_salt()
                    content = '%s salt=%s' % (password, salt)
                else:
                    content = password
                with open(path, 'w') as f:
                    os.chmod(path, 0o600)
                    f.write(content + '\n')
            else:
                content = open(path).read().rstrip()

                password = content
                salt = None
                if params['encrypt'] is not None:
                    try:
                        sep = content.rindex(' ')
                    except ValueError:
                        # No salt
                        pass
                    else:
                        salt_field = content[sep + 1:]
                        if salt_field.startswith('salt='):
                            password = content[:sep]
                            salt = salt_field[len('salt='):]

                    # crypt requested, add salt if missing
                    if not salt:
                        salt = self.random_salt()
                        content = '%s salt=%s' % (password, salt)
                        with open(path, 'w') as f:
                            os.chmod(path, 0o600)
                            f.write(content + '\n')

            if params['encrypt']:
                password = do_encrypt(password, params['encrypt'], salt=salt)

            ret.append(password)

        return ret
예제 #9
0
    def _do_var_prompt(self,
                       varname,
                       private=True,
                       prompt=None,
                       encrypt=None,
                       confirm=False,
                       salt_size=None,
                       salt=None,
                       default=None):

        if sys.__stdin__.isatty():
            if prompt and default is not None:
                msg = "%s [%s]: " % (prompt, default)
            elif prompt:
                msg = "%s: " % prompt
            else:
                msg = 'input for %s: ' % varname

            def do_prompt(prompt, private):
                if sys.stdout.encoding:
                    msg = prompt.encode(sys.stdout.encoding)
                else:
                    # when piping the output, or at other times when stdout
                    # may not be the standard file descriptor, the stdout
                    # encoding may not be set, so default to something sane
                    msg = prompt.encode(locale.getpreferredencoding())
                if private:
                    return getpass.getpass(msg)
                return raw_input(msg)

            if confirm:
                while True:
                    result = do_prompt(msg, private)
                    second = do_prompt("confirm " + msg, private)
                    if result == second:
                        break
                    self._display.display(
                        "***** VALUES ENTERED DO NOT MATCH ****")
            else:
                result = do_prompt(msg, private)
        else:
            result = None
            self._display.warning(
                "Not prompting as we are not in interactive mode")

        # if result is false and default is not None
        if not result and default is not None:
            result = default

        if encrypt:
            result = do_encrypt(result, encrypt, salt_size, salt)

        # handle utf-8 chars
        result = to_unicode(result, errors='strict')
        return result
예제 #10
0
    def do_var_prompt(self,
                      varname,
                      private=True,
                      prompt=None,
                      encrypt=None,
                      confirm=False,
                      salt_size=None,
                      salt=None,
                      default=None,
                      unsafe=None):

        result = None
        if sys.__stdin__.isatty():

            do_prompt = self.prompt

            if prompt and default is not None:
                msg = "%s [%s]: " % (prompt, default)
            elif prompt:
                msg = "%s: " % prompt
            else:
                msg = 'input for %s: ' % varname

            if confirm:
                while True:
                    result = do_prompt(msg, private)
                    second = do_prompt("confirm " + msg, private)
                    if result == second:
                        break
                    self.display("***** VALUES ENTERED DO NOT MATCH ****")
            else:
                result = do_prompt(msg, private)
        else:
            result = None
            self.warning("Not prompting as we are not in interactive mode")

        # if result is false and default is not None
        if not result and default is not None:
            result = default

        if encrypt:
            # Circular import because encrypt needs a display class
            from ansible.utils.encrypt import do_encrypt
            result = do_encrypt(result, encrypt, salt_size, salt)

        # handle utf-8 chars
        result = to_text(result, errors='surrogate_or_strict')

        if unsafe:
            result = wrap_var(result)
        return result
예제 #11
0
 def run(self, tmp=None, task_vars=dict()):
     """
     Convert the "password" argument to a hashed password.
     Then call the actual module to do the work.
     """
     options = self._task.args.copy()
     if 'password' in options:
         plain = options['password']
         digest = 'pbkdf2_sha512_osx'
         kwargs = {}
         if 'salt' in options:
             kwargs['salt'] = ab64_decode(options['salt'])
         options['password'] = do_encrypt(plain, digest, **kwargs)
     return self._execute_module(module_name="osxpassword",
                                 module_args=options,
                                 task_vars=task_vars)
예제 #12
0
 def run(self, tmp=None, task_vars=dict()):
     """
     Convert the "password" argument to a hashed password.
     Then call the actual module to do the work.
     """
     options = self._task.args.copy()
     if 'password' in options:
         plain = options['password']
         digest = 'pbkdf2_sha512_osx'
         kwargs = {}
         if 'salt' in options:
             kwargs['salt'] = ab64_decode(options['salt'])
         options['password'] = do_encrypt(plain, digest, **kwargs)
     return self._execute_module(
         module_name="osxpassword",
         module_args=options,
         task_vars=task_vars)
    def _do_var_prompt(self, varname, private=True, prompt=None, encrypt=None, confirm=False, salt_size=None, salt=None, default=None):

        if sys.__stdin__.isatty():
            if prompt and default is not None:
                msg = "%s [%s]: " % (prompt, default)
            elif prompt:
                msg = "%s: " % prompt
            else:
                msg = 'input for %s: ' % varname

            def do_prompt(prompt, private):
                if sys.stdout.encoding:
                    msg = prompt.encode(sys.stdout.encoding)
                else:
                    # when piping the output, or at other times when stdout
                    # may not be the standard file descriptor, the stdout
                    # encoding may not be set, so default to something sane
                    msg = prompt.encode(locale.getpreferredencoding())
                if private:
                    return getpass.getpass(msg)
                return raw_input(msg)

            if confirm:
                while True:
                    result = do_prompt(msg, private)
                    second = do_prompt("confirm " + msg, private)
                    if result == second:
                        break
                    self._display.display("***** VALUES ENTERED DO NOT MATCH ****")
            else:
                result = do_prompt(msg, private)
        else:
            result = None
            self._display.warning("Not prompting as we are not in interactive mode")

        # if result is false and default is not None
        if not result and default is not None:
            result = default

        if encrypt:
            result = do_encrypt(result, encrypt, salt_size, salt)

        # handle utf-8 chars
        result = to_unicode(result, errors='strict')
        return result
예제 #14
0
    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
예제 #15
0
    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
예제 #16
0
def test_do_encrypt_passlib():
    with pytest.raises(AnsibleError):
        encrypt.do_encrypt("123", "sha257_crypt", salt="12345678")

    # Uses passlib default rounds value for sha256 matching crypt behaviour.
    assert encrypt.do_encrypt("123", "sha256_crypt", salt="12345678") == "$5$rounds=535000$12345678$uy3TurUPaY71aioJi58HvUY8jkbhSQU8HepbyaNngv."

    assert encrypt.do_encrypt("123", "md5_crypt", salt="12345678") == "$1$12345678$tRy4cXc3kmcfRZVj4iFXr/"

    assert encrypt.do_encrypt("123", "crypt16", salt="12") == "12pELHK2ME3McUFlHxel6uMM"

    assert encrypt.do_encrypt("123", "bcrypt",
                              salt='1234567890123456789012',
                              ident='2a') == "$2a$12$123456789012345678901ugbM1PeTfRQ0t6dCJu5lQA8hwrZOYgDu"
예제 #17
0
    def do_var_prompt(self, varname, private=True, prompt=None, encrypt=None, confirm=False, salt_size=None, salt=None, default=None):

        result = None
        if sys.__stdin__.isatty():

            do_prompt = self.prompt

            if prompt and default is not None:
                msg = "%s [%s]: " % (prompt, default)
            elif prompt:
                msg = "%s: " % prompt
            else:
                msg = 'input for %s: ' % varname

            if confirm:
                while True:
                    result = do_prompt(msg, private)
                    second = do_prompt("confirm " + msg, private)
                    if result == second:
                        break
                    self.display("***** VALUES ENTERED DO NOT MATCH ****")
            else:
                result = do_prompt(msg, private)
        else:
            result = None
            self.warning("Not prompting as we are not in interactive mode")

        # if result is false and default is not None
        if not result and default is not None:
            result = default

        if encrypt:
            # Circular import because encrypt needs a display class
            from ansible.utils.encrypt import do_encrypt
            result = do_encrypt(result, encrypt, salt_size, salt)

        # handle utf-8 chars
        result = to_unicode(result, errors='strict')
        return result
예제 #18
0
def test_do_encrypt_passlib():
    with pytest.raises(AnsibleError):
        encrypt.do_encrypt("123", "sha257_crypt", salt="12345678")

    # Uses 5000 rounds by default for sha256 matching crypt behaviour.
    assert encrypt.do_encrypt(
        "123", "sha256_crypt", salt="12345678"
    ) == "$5$12345678$uAZsE3BenI2G.nA8DpTl.9Dc8JiqacI53pEqRr5ppT7"

    assert encrypt.do_encrypt(
        "123", "md5_crypt",
        salt="12345678") == "$1$12345678$tRy4cXc3kmcfRZVj4iFXr/"

    assert encrypt.do_encrypt("123", "crypt16",
                              salt="12") == "12pELHK2ME3McUFlHxel6uMM"

    assert encrypt.do_encrypt(
        "123", "bcrypt", salt='1234567890123456789012', ident='2a'
    ) == "$2a$12$123456789012345678901ugbM1PeTfRQ0t6dCJu5lQA8hwrZOYgDu"
예제 #19
0
    def run(self, terms, variables, **kwargs):

        ret = []

        if not isinstance(terms, list):
            terms = [ terms ]

        for term in terms:
            # you can't have escaped spaces in yor pathname
            params = term.split()
            relpath = params[0]

            paramvals = {
                'length': DEFAULT_LENGTH,
                'encrypt': None,
                'chars': ['ascii_letters','digits',".,:-_"],
            }

            # get non-default parameters if specified
            try:
                for param in params[1:]:
                    name, value = param.split('=')
                    assert(name in paramvals)
                    if name == 'length':
                        paramvals[name] = int(value)
                    elif name == 'chars':
                        use_chars=[]
                        if ",," in value: 
                            use_chars.append(',')
                        use_chars.extend(value.replace(',,',',').split(','))
                        paramvals['chars'] = use_chars
                    else:
                        paramvals[name] = value
            except (ValueError, AssertionError) as e:
                raise AnsibleError(e)

            length  = paramvals['length']
            encrypt = paramvals['encrypt']
            use_chars = paramvals['chars']

            # get password or create it if file doesn't exist
            path = self._loader.path_dwim(relpath)
            if not os.path.exists(path):
                pathdir = os.path.dirname(path)
                if not os.path.isdir(pathdir):
                    try:
                        os.makedirs(pathdir, mode=0o700)
                    except OSError as e:
                        raise AnsibleError("cannot create the path for the password lookup: %s (error was %s)" % (pathdir, str(e)))

                chars = "".join([getattr(string,c,c) for c in use_chars]).replace('"','').replace("'",'')
                password = ''.join(random.choice(chars) for _ in range(length))

                if encrypt is not None:
                    salt = self.random_salt()
                    content = '%s salt=%s' % (password, salt)
                else:
                    content = password
                with open(path, 'w') as f:
                    os.chmod(path, 0o600)
                    f.write(content + '\n')
            else:
                content = open(path).read().rstrip()
                sep = content.find(' ')

                if sep >= 0:
                    password = content[:sep]
                    salt = content[sep+1:].split('=')[1]
                else:
                    password = content
                    salt = None

                # crypt requested, add salt if missing
                if (encrypt is not None and not salt):
                    salt = self.random_salt()
                    content = '%s salt=%s' % (password, salt)
                    with open(path, 'w') as f:
                        os.chmod(path, 0o600)
                        f.write(content + '\n')
                # crypt not requested, remove salt if present
                elif (encrypt is None and salt):
                    with open(path, 'w') as f:
                        os.chmod(path, 0o600)
                        f.write(password + '\n')

            if encrypt:
                password = do_encrypt(password, encrypt, salt=salt)

            ret.append(password)

        return ret
예제 #20
0
    def run(self, terms, variables, **kwargs):

        ret = []

        for term in terms:
            # you can't have escaped spaces in yor pathname
            params = term.split()
            relpath = params[0]

            paramvals = {
                'length': DEFAULT_LENGTH,
                'encrypt': None,
                'chars': ['ascii_letters', 'digits', ".,:-_"],
            }

            # get non-default parameters if specified
            try:
                for param in params[1:]:
                    name, value = param.split('=')
                    assert (name in paramvals)
                    if name == 'length':
                        paramvals[name] = int(value)
                    elif name == 'chars':
                        use_chars = []
                        if ",," in value:
                            use_chars.append(',')
                        use_chars.extend(value.replace(',,', ',').split(','))
                        paramvals['chars'] = use_chars
                    else:
                        paramvals[name] = value
            except (ValueError, AssertionError) as e:
                raise AnsibleError(e)

            length = paramvals['length']
            encrypt = paramvals['encrypt']
            use_chars = paramvals['chars']

            # get password or create it if file doesn't exist
            path = self._loader.path_dwim(relpath)
            if not os.path.exists(path):
                pathdir = os.path.dirname(path)
                try:
                    makedirs_safe(pathdir, mode=0o700)
                except OSError as e:
                    raise AnsibleError(
                        "cannot create the path for the password lookup: %s (error was %s)"
                        % (pathdir, str(e)))

                chars = "".join([getattr(string, c, c) for c in use_chars
                                 ]).replace('"', '').replace("'", '')
                password = ''.join(random.choice(chars) for _ in range(length))

                if encrypt is not None:
                    salt = self.random_salt()
                    content = '%s salt=%s' % (password, salt)
                else:
                    content = password
                with open(path, 'w') as f:
                    os.chmod(path, 0o600)
                    f.write(content + '\n')
            else:
                content = open(path).read().rstrip()
                sep = content.find(' ')

                if sep >= 0:
                    password = content[:sep]
                    salt = content[sep + 1:].split('=')[1]
                else:
                    password = content
                    salt = None

                # crypt requested, add salt if missing
                if (encrypt is not None and not salt):
                    salt = self.random_salt()
                    content = '%s salt=%s' % (password, salt)
                    with open(path, 'w') as f:
                        os.chmod(path, 0o600)
                        f.write(content + '\n')
                # crypt not requested, remove salt if present
                elif (encrypt is None and salt):
                    with open(path, 'w') as f:
                        os.chmod(path, 0o600)
                        f.write(password + '\n')

            if encrypt:
                password = do_encrypt(password, encrypt, salt=salt)

            ret.append(password)

        return ret
예제 #21
0
                content = open(path).read().rstrip()
                sep = content.find(' ')

                if sep >= 0:
                    password = content[:sep]
                    salt = content[sep+1:].split('=')[1]
                else:
                    password = content
                    salt = None

                # crypt requested, add salt if missing
                if (encrypt is not None and not salt):
                    salt = self.random_salt()
                    content = '%s salt=%s' % (password, salt)
                    with open(path, 'w') as f:
                        os.chmod(path, 0600)
                        f.write(content + '\n')
                # crypt not requested, remove salt if present
                elif (encrypt is None and salt):
                    with open(path, 'w') as f:
                        os.chmod(path, 0600)
                        f.write(password + '\n')

            if encrypt:
                password = do_encrypt(password, encrypt, salt=salt)

            ret.append(password)

        return ret