def EnsureSSHKeyExistsForUser(self, user): """Ensure the user's public SSH key is known by the Account Service.""" public_key = self.GetPublicKey() should_upload = True try: user_info = self.LookupUser(user) except user_utils.UserException: owner_email = gaia_utils.GetAuthenticatedGaiaEmail(self.http) self.CreateUser(user, owner_email) user_info = self.LookupUser(user) for remote_public_key in user_info.publicKeys: if remote_public_key.key.rstrip() == public_key: expiration_time = remote_public_key.expirationTimestamp if expiration_time and time_utils.IsExpired(expiration_time): # If a key is expired we remove and reupload self.RemovePublicKey(user_info.name, remote_public_key.fingerprint) else: should_upload = False break if should_upload: self.UploadPublicKey(user, public_key) return True
def CreateRequests(self, args): """Returns a list of requests necessary for adding users.""" owner = args.owner if not owner: owner = gaia_utils.GetAuthenticatedGaiaEmail(self.http) name = args.name if not name: name = gaia_utils.MapGaiaEmailToDefaultAccountName(owner) user_ref = self.CreateAccountsReference(name, resource_type='users') user = self.messages.User( name=user_ref.Name(), description=args.description, owner=owner, ) request = self.messages.ClouduseraccountsUsersInsertRequest( project=self.project, user=user) return [request]
def Run(self, args): start = time_utils.CurrentTimeSec() # Set up Encryption utilities. openssl_executable = files.FindExecutableOnPath('openssl') if windows_encryption_utils: crypt = windows_encryption_utils.WinCrypt() elif openssl_executable: crypt = openssl_encryption_utils.OpensslCrypt(openssl_executable) else: raise utils.MissingDependencyError( 'Your platform does not support OpenSSL.') # Get Authenticated email address and default username. email = gaia_utils.GetAuthenticatedGaiaEmail(self.http) if args.user: user = args.user else: user = gaia_utils.MapGaiaEmailToDefaultAccountName(email) if args.name == user: raise utils.InvalidUserError( MACHINE_USERNAME_SAME_ERROR.format(user, args.name)) # Warn user (This warning doesn't show for non-interactive sessions). message = RESET_PASSWORD_WARNING.format(user) prompt_string = ( 'Would you like to set or reset the password for [{0}]'.format( user)) console_io.PromptContinue(message=message, prompt_string=prompt_string, cancel_on_no=True) log.status.Print( 'Resetting and retrieving password for [{0}] on [{1}]'.format( user, args.name)) # Get Encryption Keys. key = crypt.GetKeyPair() modulus, exponent = crypt.GetModulusExponentFromPublicKey( crypt.GetPublicKey(key)) # Create Windows key entry. self.windows_key_entry = self._ConstructWindowsKeyEntry( user, modulus, exponent, email) # Call ReadWriteCommad.Run() which will fetch the instance and update # the metadata (using the data in self.windows_key_entry). objects = super(ResetWindowsPassword, self).Run(args) updated_instance = list(objects)[0] # Retrieve and Decrypt the password from the serial console. enc_password = self._GetEncryptedPasswordFromSerialPort(modulus) password = crypt.DecryptMessage(key, enc_password) # Get External IP address. try: access_configs = updated_instance['networkInterfaces'][0][ 'accessConfigs'] external_ip_address = access_configs[0]['natIP'] except KeyError: log.warn(NO_IP_WARNING.format(updated_instance['name'])) external_ip_address = None # Check for old Windows credentials. if self.old_metadata_keys: log.warn( OLD_KEYS_WARNING.format(self.ref.Name(), self.ref.Name(), self.ref.zone, ','.join(self.old_metadata_keys))) log.info('Total Elapsed Time: {0}'.format(time_utils.CurrentTimeSec() - start)) # The connection info resource. connection_info = { 'username': user, 'password': password, 'ip_address': external_ip_address } return connection_info