Repository: ansible/ansible

Issue:
Ansible Vault fails to decode files with CRLF line endings
##### ISSUE TYPE
 - Bug Report

##### COMPONENT NAME
Vault

##### ANSIBLE VERSION
```
ansible 2.2.1.0
```

##### CONFIGURATION
Default

##### OS / ENVIRONMENT
Windows Subsystem for Linux; Ubuntu 16.04

##### SUMMARY
Ansible Vault fails to decode files with CRLF line endings
##### STEPS TO REPRODUCE
After saving an file that is encrypted with vault, convert the line endings from LF to CRLF. This happens innocuously when using Git's EOL auto conversion feature.

##### EXPECTED RESULTS
The vault encrypted file is decrypted and used in the operation.

##### ACTUAL RESULTS
```
ansible-vault edit group_vars/role/vault.yml --vault-password-file=vault_pass -vvv
Using /etc/ansible/ansible.cfg as config file
[DEPRECATION WARNING]: ansible.utils.unicode.to_unicode is deprecated.  Use ansible.module_utils._text.to_text instead.
This feature will be removed
in version 2.4. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
ERROR! Unexpected Exception: Odd-length string
the full traceback was:

Traceback (most recent call last):
  File "/usr/bin/ansible-vault", line 85, in <module>
    sys.exit(cli.run())
  File "/home/user/.local/lib/python2.7/site-packages/ansible/cli/vault.py", line 122, in run
    self.execute()
  File "/home/user/.local/lib/python2.7/site-packages/ansible/cli/__init__.py", line 145, in execute
    fn()
  File "/home/user/.local/lib/python2.7/site-packages/ansible/cli/vault.py", line 158, in execute_edit
    self.editor.edit_file(f)
  File "/home/user/.local/lib/python2.7/site-packages/ansible/parsing/vault/__init__.py", line 456, in edit_file
    plaintext = self.vault.decrypt(ciphertext)
  File "/home/user/.local/lib/python2.7/site-packages/ansible/parsing/vault/__init__.py", line 259, in decrypt
    b_plaintext = this_cipher.decrypt(b_vaulttext, self.b_password)
  File "/home/user/.local/lib/python2.7/site-packages/ansible/parsing/vault/__init__.py", line 743, in decrypt
    b_vaulttext = unhexlify(b_vaulttext)
TypeError: Odd-length string
```



Discussion:
There is a bit in parsing vaulttext that splits on b'\n', just needs to use splitlines() instead. pr incoming... 

Resolving patch:
diff --git a/lib/ansible/parsing/vault/__init__.py b/lib/ansible/parsing/vault/__init__.py
--- a/lib/ansible/parsing/vault/__init__.py
+++ b/lib/ansible/parsing/vault/__init__.py
@@ -159,7 +159,7 @@ def parse_vaulttext_envelope(b_vaulttext_envelope, default_vault_id=None):
     # used by decrypt
     default_vault_id = default_vault_id or C.DEFAULT_VAULT_IDENTITY
 
-    b_tmpdata = b_vaulttext_envelope.split(b'\n')
+    b_tmpdata = b_vaulttext_envelope.splitlines()
     b_tmpheader = b_tmpdata[0].strip().split(b';')
 
     b_version = b_tmpheader[1].strip()


Test patch:
diff --git a/test/units/parsing/vault/test_vault.py b/test/units/parsing/vault/test_vault.py
--- a/test/units/parsing/vault/test_vault.py
+++ b/test/units/parsing/vault/test_vault.py
@@ -516,6 +516,14 @@ def test_parse_vaulttext_envelope(self):
         self.assertEqual(cipher_name, u'TEST', msg="cipher name was not properly set")
         self.assertEqual(b_version, b"9.9", msg="version was not properly set")
 
+    def test_parse_vaulttext_envelope_crlf(self):
+        b_vaulttext = b"$ANSIBLE_VAULT;9.9;TEST\r\nansible"
+        b_ciphertext, b_version, cipher_name, vault_id = vault.parse_vaulttext_envelope(b_vaulttext)
+        b_lines = b_ciphertext.split(b'\n')
+        self.assertEqual(b_lines[0], b"ansible", msg="Payload was not properly split from the header")
+        self.assertEqual(cipher_name, u'TEST', msg="cipher name was not properly set")
+        self.assertEqual(b_version, b"9.9", msg="version was not properly set")
+
     def test_encrypt_decrypt_aes(self):
         self.v.cipher_name = u'AES'
         vault_secrets = self._vault_secrets_from_password('default', 'ansible')