Exemple #1
0
    def CreateRequests(self, args):
        """Returns a list of requests necessary for adding users."""

        owner = args.owner
        if not owner:
            owner = gaia.GetAuthenticatedGaiaEmail(self.http)

        name = args.name
        if not name:
            name = gaia.MapGaiaEmailToDefaultAccountName(owner)

        user_ref = self.clouduseraccounts_resources.Parse(
            name,
            params={'project': properties.VALUES.core.project.GetOrFail},
            collection='clouduseraccounts.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]
Exemple #2
0
    def _EnsureSSHKeyExistsForUser(self, fetcher, user):
        """Ensure the user's public SSH key is known by the Account Service."""
        public_key = self.keys.GetPublicKey().ToEntry(include_comment=True)
        should_upload = True
        try:
            user_info = fetcher.LookupUser(user)
        except user_client.UserException:
            owner_email = gaia.GetAuthenticatedGaiaEmail(self.http)
            fetcher.CreateUser(user, owner_email)
            user_info = fetcher.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_util.IsExpired(expiration_time):
                    # If a key is expired we remove and reupload
                    fetcher.RemovePublicKey(user_info.name,
                                            remote_public_key.fingerprint)
                else:
                    should_upload = False
                break

        if should_upload:
            fetcher.UploadPublicKey(user, public_key)
        return True
    def Run(self, args):
        """Issues requests necessary for adding users."""
        compute_holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
        holder = base_classes.ComputeUserAccountsApiHolder(self.ReleaseTrack())
        client = holder.client

        owner = args.owner
        if not owner:
            owner = gaia.GetAuthenticatedGaiaEmail(client.http)

        name = args.name
        if not name:
            name = gaia.MapGaiaEmailToDefaultAccountName(owner)

        user_ref = holder.resources.Parse(
            name,
            params={'project': properties.VALUES.core.project.GetOrFail},
            collection='clouduseraccounts.users')

        user = client.MESSAGES_MODULE.User(
            name=user_ref.Name(),
            description=args.description,
            owner=owner,
        )

        request = client.MESSAGES_MODULE.ClouduseraccountsUsersInsertRequest(
            project=user_ref.project, user=user)
        return compute_holder.client.MakeRequests([(client.users, 'Insert',
                                                    request)])
Exemple #4
0
    def Run(self, args):
        """See ssh_utils.BaseSSHCLICommand.Run."""

        oslogin_client = client.OsloginClient(self.ReleaseTrack())
        user_email = gaia.GetAuthenticatedGaiaEmail(oslogin_client.client.http)

        keys = oslogin_utils.GetKeysFromProfile(user_email, oslogin_client)
        return keys
Exemple #5
0
    def Run(self, args):
        """See ssh_utils.BaseSSHCLICommand.Run."""
        key = flags.GetKeyFromArgs(args)
        oslogin_client = client.OsloginClient(self.ReleaseTrack())
        user_email = gaia.GetAuthenticatedGaiaEmail(oslogin_client.client.http)

        keys = oslogin_utils.GetKeyDictionaryFromProfile(
            user_email, oslogin_client)
        fingerprint = oslogin_utils.FindKeyInKeyList(key, keys)
        if fingerprint:
            return oslogin_client.DeleteSshPublicKey(user_email, fingerprint)
        else:
            raise client.OsloginKeyNotFoundError(
                'Cannot find requested SSH key.')
    def CheckForOsloginAndGetUser(self, instance, project, requested_user,
                                  release_track, http):
        """Checks instance/project metadata for oslogin and update username."""
        # Instance metadata has priority
        use_oslogin = False
        oslogin_enabled = _MetadataHasOsloginEnable(instance.metadata)
        if oslogin_enabled is None:
            project_metadata = project.commonInstanceMetadata
            oslogin_enabled = _MetadataHasOsloginEnable(project_metadata)

        if not oslogin_enabled:
            return requested_user, use_oslogin

        # Connect to the oslogin API and add public key to oslogin user account.
        oslogin = oslogin_client.OsloginClient(release_track)
        if not oslogin:
            log.warn(
                'OS Login is enabled on Instance/Project, but is not availabe '
                'in the {0} version of gcloud.'.format(release_track.id))
            return requested_user, use_oslogin
        public_key = self.keys.GetPublicKey().ToEntry(include_comment=True)
        user_email = gaia.GetAuthenticatedGaiaEmail(http)
        login_profile = oslogin.ImportSshPublicKey(user_email, public_key)
        use_oslogin = True

        # Get the username for the oslogin user. If the username is the same as the
        # default user, return that one. Otherwise, return the 'primary' username.
        # If no 'primary' exists, return the first username.
        oslogin_user = None
        for pa in login_profile.loginProfile.posixAccounts:
            oslogin_user = oslogin_user or pa.username
            if pa.username == requested_user:
                return requested_user, use_oslogin
            elif pa.primary:
                oslogin_user = pa.username

        log.warn(
            'Using OS Login user [{0}] instead of default user [{1}]'.format(
                oslogin_user, requested_user))
        return oslogin_user, use_oslogin
Exemple #7
0
  def Run(self, args):
    """Issues requests necessary for adding users."""
    holder = base_classes.ComputeUserAccountsApiHolder(self.ReleaseTrack())
    client = holder.client

    owner = args.owner
    if not owner:
      owner = gaia.GetAuthenticatedGaiaEmail(client.http)

    name = args.name
    if not name:
      name = gaia.MapGaiaEmailToDefaultAccountName(owner)

    user_ref = holder.resources.Parse(
        name,
        params={'project': properties.VALUES.core.project.GetOrFail},
        collection='clouduseraccounts.users')

    user = client.MESSAGES_MODULE.User(
        name=user_ref.Name(),
        description=args.description,
        owner=owner,
    )

    request = client.MESSAGES_MODULE.ClouduseraccountsUsersInsertRequest(
        project=user_ref.project,
        user=user)

    errors = []
    responses = list(
        request_helper.MakeRequests(
            requests=[(client.users, 'Insert', request)],
            http=client.http,
            batch_url='https://www.googleapis.com/batch/',
            errors=errors))
    if errors:
      utils.RaiseToolException(
          errors, error_message='Could not fetch resource:')
    return responses
Exemple #8
0
    def Run(self, args):
        start = time_util.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.GetAuthenticatedGaiaEmail(self.http)
        if args.user:
            user = args.user
        else:
            user = gaia.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_util.CurrentTimeSec() -
                                                  start))

        # The connection info resource.
        connection_info = {
            'username': user,
            'password': password,
            'ip_address': external_ip_address
        }
        return connection_info
Exemple #9
0
    def Run(self, args):
        holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
        client = holder.client
        start = time_util.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.GetAuthenticatedGaiaEmail(client.apitools_client.http)
        if args.user:
            user = args.user
        else:
            user = gaia.MapGaiaEmailToDefaultAccountName(email)

        if args.instance_name == user:
            raise utils.InvalidUserError(
                MACHINE_USERNAME_SAME_ERROR.format(user, args.instance_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.instance_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).
        instance_ref = self.CreateReference(client, holder.resources, args)
        get_request = self.GetGetRequest(client, instance_ref)

        objects = client.MakeRequests([get_request])

        new_object = self.Modify(client, objects[0])

        # If existing object is equal to the proposed object or if
        # Modify() returns None, then there is no work to be done, so we
        # print the resource and return.
        if objects[0] == new_object:
            log.status.Print(
                'No change requested; skipping update for [{0}].'.format(
                    objects[0].name))
            return objects

        updated_instance = client.MakeRequests(
            [self.GetSetRequest(client, instance_ref, new_object)])[0]

        # Retrieve and Decrypt the password from the serial console.
        enc_password = self._GetEncryptedPasswordFromSerialPort(
            client, instance_ref, 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, IndexError) as _:
            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(instance_ref.instance,
                                        instance_ref.instance,
                                        instance_ref.zone,
                                        ','.join(self.old_metadata_keys)))

        log.info('Total Elapsed Time: {0}'.format(time_util.CurrentTimeSec() -
                                                  start))

        # The connection info resource.
        connection_info = {
            'username': user,
            'password': password,
            'ip_address': external_ip_address
        }
        return connection_info