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_USERNAME=<user-name> | ||||
|    export OS_PASSWORD=<password>  # (optional) | ||||
|    export OS_USE_KEYRING=true  # (optional) | ||||
|  | ||||
| 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-username <user-name> | ||||
|    [--os-password <password>] | ||||
|    [--os-use-keyring] | ||||
|  | ||||
| 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 | ||||
| in the prompt is stored in keyring. From next time, the password is read from | ||||
| keyring, if it is not provided above (in plaintext). | ||||
| prompted to provide one securely. | ||||
|  | ||||
| The token flow variation for authentication uses an already-acquired token | ||||
| and a URL pointing directly to the service API that presumably was acquired | ||||
|   | ||||
| @@ -68,9 +68,6 @@ OPTIONS | ||||
| :option:`--os-default-domain` <auth-domain> | ||||
|     Default domain ID (Default: 'default') | ||||
|  | ||||
| :option:`--os-use-keyring` | ||||
|     Use keyring to store password (default: False) | ||||
|  | ||||
| :option:`--os-cacert` <ca-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` | ||||
|     Default domain ID (Default: ‘default’) | ||||
|  | ||||
| :envvar:`OS_USE_KEYRING` | ||||
|     Use keyring to store password (default: False) | ||||
|  | ||||
| :envvar:`OS_CACERT` | ||||
|     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 commandmanager | ||||
| from openstackclient.common import exceptions as exc | ||||
| from openstackclient.common import openstackkeyring | ||||
| from openstackclient.common import restapi | ||||
| from openstackclient.common import utils | ||||
| from openstackclient.identity import client as identity_client | ||||
| @@ -305,18 +304,6 @@ class OpenStackShell(app.App): | ||||
|             default=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( | ||||
|             '--os-identity-api-version', | ||||
|             metavar='<identity-api-version>', | ||||
| @@ -352,14 +339,12 @@ class OpenStackShell(app.App): | ||||
|                     "You must provide a username via" | ||||
|                     " either --os-username or env[OS_USERNAME]") | ||||
|  | ||||
|             self.get_password_from_keyring() | ||||
|             if not self.options.os_password: | ||||
|                 # No password, if we've got a tty, try prompting for it | ||||
|                 if hasattr(sys.stdin, 'isatty') and sys.stdin.isatty(): | ||||
|                     # Check for Ctl-D | ||||
|                     try: | ||||
|                         self.options.os_password = getpass.getpass() | ||||
|                         self.set_password_in_keyring() | ||||
|                     except EOFError: | ||||
|                         pass | ||||
|                 # No password because we did't have a tty or the | ||||
| @@ -406,34 +391,6 @@ class OpenStackShell(app.App): | ||||
|         ) | ||||
|         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): | ||||
|         """Global app init bits: | ||||
|  | ||||
|   | ||||
| @@ -1,7 +1,5 @@ | ||||
| pbr>=0.6,!=0.7,<1.0 | ||||
| cliff>=1.6.0 | ||||
| keyring>=2.1 | ||||
| pycrypto>=2.6 | ||||
| python-glanceclient>=0.13.1 | ||||
| python-keystoneclient>=0.9.0 | ||||
| python-novaclient>=2.17.0 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user