Remove keyring support from openstackclient
* The encryption it purports to offer is completely insecure. * It also appears to be broken. Closes-Bug: #1319381 Change-Id: Id15ecfbbfd15f142b14c125bfd85afd5032699ac
This commit is contained in:
		 Alex Gaynor
					Alex Gaynor
				
			
				
					committed by
					
						 Steve Martinelli
						Steve Martinelli
					
				
			
			
				
	
			
			
			 Steve Martinelli
						Steve Martinelli
					
				
			
						parent
						
							0ab1791439
						
					
				
				
					commit
					b8f534df01
				
			| @@ -79,7 +79,6 @@ The 'password flow' variation is most commonly used:: | |||||||
|    export OS_PROJECT_NAME=<project-name> |    export OS_PROJECT_NAME=<project-name> | ||||||
|    export OS_USERNAME=<user-name> |    export OS_USERNAME=<user-name> | ||||||
|    export OS_PASSWORD=<password>  # (optional) |    export OS_PASSWORD=<password>  # (optional) | ||||||
|    export OS_USE_KEYRING=true  # (optional) |  | ||||||
|  |  | ||||||
| The corresponding command-line options look very similar:: | The corresponding command-line options look very similar:: | ||||||
|  |  | ||||||
| @@ -87,12 +86,9 @@ The corresponding command-line options look very similar:: | |||||||
|    --os-project-name <project-name> |    --os-project-name <project-name> | ||||||
|    --os-username <user-name> |    --os-username <user-name> | ||||||
|    [--os-password <password>] |    [--os-password <password>] | ||||||
|    [--os-use-keyring] |  | ||||||
|  |  | ||||||
| If a password is not provided above (in plaintext), you will be interactively | If a password is not provided above (in plaintext), you will be interactively | ||||||
| prompted to provide one securely. If keyring is enabled, the password entered | prompted to provide one securely. | ||||||
| in the prompt is stored in keyring. From next time, the password is read from |  | ||||||
| keyring, if it is not provided above (in plaintext). |  | ||||||
|  |  | ||||||
| The token flow variation for authentication uses an already-acquired token | The token flow variation for authentication uses an already-acquired token | ||||||
| and a URL pointing directly to the service API that presumably was acquired | and a URL pointing directly to the service API that presumably was acquired | ||||||
|   | |||||||
| @@ -68,9 +68,6 @@ OPTIONS | |||||||
| :option:`--os-default-domain` <auth-domain> | :option:`--os-default-domain` <auth-domain> | ||||||
|     Default domain ID (Default: 'default') |     Default domain ID (Default: 'default') | ||||||
|  |  | ||||||
| :option:`--os-use-keyring` |  | ||||||
|     Use keyring to store password (default: False) |  | ||||||
|  |  | ||||||
| :option:`--os-cacert` <ca-bundle-file> | :option:`--os-cacert` <ca-bundle-file> | ||||||
|     CA certificate bundle file |     CA certificate bundle file | ||||||
|  |  | ||||||
| @@ -175,9 +172,6 @@ The following environment variables can be set to alter the behaviour of :progra | |||||||
| :envvar:`OS_DEFAULT_DOMAIN` | :envvar:`OS_DEFAULT_DOMAIN` | ||||||
|     Default domain ID (Default: ‘default’) |     Default domain ID (Default: ‘default’) | ||||||
|  |  | ||||||
| :envvar:`OS_USE_KEYRING` |  | ||||||
|     Use keyring to store password (default: False) |  | ||||||
|  |  | ||||||
| :envvar:`OS_CACERT` | :envvar:`OS_CACERT` | ||||||
|     CA certificate bundle file |     CA certificate bundle file | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,60 +0,0 @@ | |||||||
| #   Copyright 2011-2013 OpenStack, LLC. |  | ||||||
| # |  | ||||||
| #   Licensed under the Apache License, Version 2.0 (the "License"); you may |  | ||||||
| #   not use this file except in compliance with the License. You may obtain |  | ||||||
| #   a copy of the License at |  | ||||||
| # |  | ||||||
| #        http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
| # |  | ||||||
| #   Unless required by applicable law or agreed to in writing, software |  | ||||||
| #   distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |  | ||||||
| #   WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |  | ||||||
| #   License for the specific language governing permissions and limitations |  | ||||||
| #   under the License. |  | ||||||
| # |  | ||||||
|  |  | ||||||
| """Keyring backend for OpenStack, to store encrypted password in a file.""" |  | ||||||
|  |  | ||||||
| from Crypto.Cipher import AES |  | ||||||
|  |  | ||||||
| import keyring |  | ||||||
| import os |  | ||||||
|  |  | ||||||
|  |  | ||||||
| KEYRING_FILE = os.path.join(os.path.expanduser('~'), '.openstack-keyring.cfg') |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class OpenStackKeyring(keyring.backends.file.BaseKeyring): |  | ||||||
|     """OpenStack Keyring to store encrypted password.""" |  | ||||||
|     filename = KEYRING_FILE |  | ||||||
|  |  | ||||||
|     def supported(self): |  | ||||||
|         """Applicable for all platforms, but not recommend.""" |  | ||||||
|         pass |  | ||||||
|  |  | ||||||
|     def _init_crypter(self): |  | ||||||
|         """Initialize the crypter using the class name.""" |  | ||||||
|         block_size = 32 |  | ||||||
|         padding = '0' |  | ||||||
|  |  | ||||||
|         # init the cipher with the class name, up to block_size |  | ||||||
|         password = __name__[block_size:] |  | ||||||
|         password = password + (block_size - len(password) % |  | ||||||
|                                block_size) * padding |  | ||||||
|         return AES.new(password, AES.MODE_CFB) |  | ||||||
|  |  | ||||||
|     def encrypt(self, password): |  | ||||||
|         """Encrypt the given password.""" |  | ||||||
|         crypter = self._init_crypter() |  | ||||||
|         return crypter.encrypt(password) |  | ||||||
|  |  | ||||||
|     def decrypt(self, password_encrypted): |  | ||||||
|         """Decrypt the given password.""" |  | ||||||
|         crypter = self._init_crypter() |  | ||||||
|         return crypter.decrypt(password_encrypted) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def os_keyring(): |  | ||||||
|     """Initialize the openstack keyring.""" |  | ||||||
|     ring = 'openstackclient.common.openstackkeyring.OpenStackKeyring' |  | ||||||
|     return keyring.core.load_keyring(None, ring) |  | ||||||
| @@ -31,7 +31,6 @@ import openstackclient | |||||||
| from openstackclient.common import clientmanager | from openstackclient.common import clientmanager | ||||||
| from openstackclient.common import commandmanager | from openstackclient.common import commandmanager | ||||||
| from openstackclient.common import exceptions as exc | from openstackclient.common import exceptions as exc | ||||||
| from openstackclient.common import openstackkeyring |  | ||||||
| from openstackclient.common import restapi | from openstackclient.common import restapi | ||||||
| from openstackclient.common import utils | from openstackclient.common import utils | ||||||
| from openstackclient.identity import client as identity_client | from openstackclient.identity import client as identity_client | ||||||
| @@ -305,18 +304,6 @@ class OpenStackShell(app.App): | |||||||
|             default=env('OS_URL'), |             default=env('OS_URL'), | ||||||
|             help='Defaults to env[OS_URL]') |             help='Defaults to env[OS_URL]') | ||||||
|  |  | ||||||
|         env_os_keyring = env('OS_USE_KEYRING', default=False) |  | ||||||
|         if type(env_os_keyring) == str: |  | ||||||
|             if env_os_keyring.lower() in ['true', '1']: |  | ||||||
|                 env_os_keyring = True |  | ||||||
|             else: |  | ||||||
|                 env_os_keyring = False |  | ||||||
|         parser.add_argument('--os-use-keyring', |  | ||||||
|                             default=env_os_keyring, |  | ||||||
|                             action='store_true', |  | ||||||
|                             help='Use keyring to store password, ' |  | ||||||
|                                  'default=False (Env: OS_USE_KEYRING)') |  | ||||||
|  |  | ||||||
|         parser.add_argument( |         parser.add_argument( | ||||||
|             '--os-identity-api-version', |             '--os-identity-api-version', | ||||||
|             metavar='<identity-api-version>', |             metavar='<identity-api-version>', | ||||||
| @@ -352,14 +339,12 @@ class OpenStackShell(app.App): | |||||||
|                     "You must provide a username via" |                     "You must provide a username via" | ||||||
|                     " either --os-username or env[OS_USERNAME]") |                     " either --os-username or env[OS_USERNAME]") | ||||||
|  |  | ||||||
|             self.get_password_from_keyring() |  | ||||||
|             if not self.options.os_password: |             if not self.options.os_password: | ||||||
|                 # No password, if we've got a tty, try prompting for it |                 # No password, if we've got a tty, try prompting for it | ||||||
|                 if hasattr(sys.stdin, 'isatty') and sys.stdin.isatty(): |                 if hasattr(sys.stdin, 'isatty') and sys.stdin.isatty(): | ||||||
|                     # Check for Ctl-D |                     # Check for Ctl-D | ||||||
|                     try: |                     try: | ||||||
|                         self.options.os_password = getpass.getpass() |                         self.options.os_password = getpass.getpass() | ||||||
|                         self.set_password_in_keyring() |  | ||||||
|                     except EOFError: |                     except EOFError: | ||||||
|                         pass |                         pass | ||||||
|                 # No password because we did't have a tty or the |                 # No password because we did't have a tty or the | ||||||
| @@ -406,34 +391,6 @@ class OpenStackShell(app.App): | |||||||
|         ) |         ) | ||||||
|         return |         return | ||||||
|  |  | ||||||
|     def init_keyring_backend(self): |  | ||||||
|         """Initialize openstack backend to use for keyring""" |  | ||||||
|         return openstackkeyring.os_keyring() |  | ||||||
|  |  | ||||||
|     def get_password_from_keyring(self): |  | ||||||
|         """Get password from keyring, if it's set""" |  | ||||||
|         if self.options.os_use_keyring: |  | ||||||
|             service = KEYRING_SERVICE |  | ||||||
|             backend = self.init_keyring_backend() |  | ||||||
|             if not self.options.os_password: |  | ||||||
|                 password = backend.get_password(service, |  | ||||||
|                                                 self.options.os_username) |  | ||||||
|                 self.options.os_password = password |  | ||||||
|  |  | ||||||
|     def set_password_in_keyring(self): |  | ||||||
|         """Set password in keyring for this user""" |  | ||||||
|         if self.options.os_use_keyring: |  | ||||||
|             service = KEYRING_SERVICE |  | ||||||
|             backend = self.init_keyring_backend() |  | ||||||
|             if self.options.os_password: |  | ||||||
|                 password = backend.get_password(service, |  | ||||||
|                                                 self.options.os_username) |  | ||||||
|                 # either password is not set in keyring, or it is different |  | ||||||
|                 if password != self.options.os_password: |  | ||||||
|                     backend.set_password(service, |  | ||||||
|                                          self.options.os_username, |  | ||||||
|                                          self.options.os_password) |  | ||||||
|  |  | ||||||
|     def initialize_app(self, argv): |     def initialize_app(self, argv): | ||||||
|         """Global app init bits: |         """Global app init bits: | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,7 +1,5 @@ | |||||||
| pbr>=0.6,!=0.7,<1.0 | pbr>=0.6,!=0.7,<1.0 | ||||||
| cliff>=1.6.0 | cliff>=1.6.0 | ||||||
| keyring>=2.1 |  | ||||||
| pycrypto>=2.6 |  | ||||||
| python-glanceclient>=0.13.1 | python-glanceclient>=0.13.1 | ||||||
| python-keystoneclient>=0.9.0 | python-keystoneclient>=0.9.0 | ||||||
| python-novaclient>=2.17.0 | python-novaclient>=2.17.0 | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user