Wednesday, August 14, 2019

Downloading GarageBand loops for Munki deployment using appleLoops.py

Among other applications, we deploy Apple's GarageBand using Munki. GarageBand can be installed without too much trouble, but on first run, it prompts the user for an administrator password so that it can download and install a set of instrument loop packages. Of course, if the user isn't an administrator - for example, a student in a lab - they won't be able to allow this installation, and will therefore be unable to launch GarageBand.

So, to avoid this problem, it's standard practice to download the loop packages for deployment through something like Munki or Jamf. The traditional way to do this involved opening GarageBand and, before entering your administrator credentials, copying the installer packages out of a path located deep within /var/folders/.... Unfortunately, at least with our modern version of GarageBand 10.3.2, this doesn't seem to be good enough: the set of packages that are downloaded, when installed onto another computer with a fresh install of GarageBand, don't satisfy the application, and it prompts to download them again. It's possible that I made some mistake, but I tried it twice, and it didn't work either time.

Fortunately, some Googling turned up a GitHub repository for a project called appleLoops.py, by Carl Ashley, that ultimately solved our issue. appleLoops.py makes it easy to download loop packages for GarageBand, Logic Pro X, and MainStage 3, and can optionally install these packages in deployment mode, usable from products like Munki and Jamf. It even lets you specify a local cache location that clients will use to download packages so that you can avoid slow or expensive transfers over the Internet.

For our purposes, simply downloading the packages is good enough, so here's how I did it:
1. Download the appleLoops.py project from GitHub.

2. Create a folder to store the loops that you will be downloading. I made this folder as a subdirectory of the appleLoops project folder, but it can be anywhere on your computer, or even a network location to which you have write access.

3. Run the appleLoops.py script:
sudo ./appleLoops.py --apps garageband --destination ./loops --mandatory-only
(If you also want the larger set of optional loops, add --optional-only to the command line. Despite both flags saying "only", they actually do combine without issue.)

4. After the loops have finished downloading, configure your management system of choice to deploy them to clients. If you don't use a management system like Jamf or Munki, you can easily write a shell script to install all of the loops packages manually:
#!/bin/bash

for pkg in $( ls *.pkg ); do
    echo "Installing $pkg"
    installer -pkg $pkg -target /
done

5. After the loops have installed, GarageBand should open without prompting for administrator credentials.

Wednesday, August 7, 2019

Whitelisting Windows Store applications on Windows using secpol.msc

As part of PCI compliance, we are required to restrict the applications which users are able to access on our payment office PCs to those on a specific whitelist. One wrinkle we've run into as part of migrating from Windows 7 to Windows 10 is that our older GPO-based method of restricting applications does not apply to newer Windows Store/Modern apps, including Microsoft Edge and Skype. This wrinkle has, so far, kept our payment PCs on Windows 7 for PCI compliance reasons.

Luckily, I discovered that it is possible to use a different method to whitelist applications: secpol.msc.  This is the Local Security Policy editor, reminiscent of the Local Group Policy editor gpedit.msc, and it allows you to create a software restriction policy to control what applications can and cannot run on a PC.

To create a software restriction policy to create an application whitelist, including Windows Store/Modern apps, follow these steps:

1. Open secpol.msc.

2. Right-click on "Software Restriction Policy", then on "New Software Restriction Policies."

3. In the "Security Levels" folder on the left, right-click on the "Disallowed" setting, then on "Set as default." This sets Windows to disallow access to all applications by default, except for those specifically whitelisted in the "Additional Rules" section below.

4. Right-click in the empty space in the "Additional Rules" folder, then on "New Path Rule...".

5. Enter the path of the application or folder that you wish to control. In this example, I am adding a rule to disallow all applications and apps in the C:\Program Files\WindowsApps folder, which includes things like the Calculator and Notepad apps. Click OK.

6. Add more rules to cover all of the applications you wish to control. As you can see in the screenshot below, I have also added a rule to disallow C:\Windows\SystemApps\*Edge*, in order to block the Microsoft Edge web browser from running. 
Note: You most likely do not want to block C:\Windows\SystemApps as a whole, because Microsoft has app-ified various parts of the operating system, including the Start menu and File Explorer. If you disallow this folder, you will lose access to these parts of the operating system until the policy is relaxed.

That's pretty much it! As you can see in the screenshots above, there are two entries that are automatically created when you create the software restriction policy: one for %HKLM [...] ProgramFilesDir%, and one for %HKLM [...] SystemRoot%. 

%SystemRoot% includes vital parts of the operating system, so it is not advisable to disallow access to this folder on a blanket level. %ProgramFilesDir% covers everything in the Program Files directory, meaning that by default some applications will still be allowed to run, even with the default policy set to disallow - Microsoft Office is an example of this. If you want to block these applications, simply change that entry from unrestricted to disallow.

In order to whitelist an application, you would do the same thing: create a new additional rule, but instead of specifying that it should be a "disallow" rule, choose "unrestricted" instead.

To make your changes take effect, log out and back in.

Tableau, TabPy, and the Case of No Input Rows

 I haven't scientifically confirmed this or anything, but it sure seems like if you pass an empty dataframe to a TabPy script, then no m...