KB Shortcut: Show Original(ity)

I hear it all the time (once): “Hey Joel! Your posts are fun and all… but what about me, the average every-man, who’s not a Mac admin?” Well, I hear you. Today, I have a Keyboard shortcut tip! Everyone loves those right? Tips like these are what some Mac blogs use to keep those daily click-thru revenues humming along! Here we go!

Aliases. Ever use those? You know, the files with the little arrows on them. The ones that have ruined many a off-site client presentation: “What do you mean ‘the original item can’t be found’?!!?! Fuuuuu…..!” Yeah, those.

An alias in the wild

Back in the “old days” (aka last year) and for decades before that (1991!), the keyboard shortcut in Finder to “Show Original” was Command-R, in fact that’s what Apple still says it is!

Command-R since 1991 meant “Show Original” aka “Reveal in Finder”

Since nothing lasts forever, it changed. Starting last year with macOS Mojave, “Show Original” is now the finger twisting Command-Option-Control-A. Why? So Command-R and Command-L could rotate your photos in Finder and QuickLook, that’s why!

See what they did there?

Daring Fireball has a great write-up screed about this, it’s hilarious and I love it, but my only critique is: not enough pictures! Well, I’m here to help, folks. Let’s figure out how to contort our hand to “Show Original” in this brave new world.

I’m trying to stay away from the “OK” sign these days…
This one is just a traffic-jam of fingers
Two handed? Has it really come to this? I need my mouse hand!

After some finger yoga and mindfulness exercises, I think I’ve come upon a way to Show Original, in a way that’s functional (one handed) and makes a statement! Here it is.

There we go! That sums it up.

Disclaimer: I am not responsible for any hand cramps or workplace misunderstandings that may arise from the use of this keyboard shortcut.

Time to Die: When Mac app and package certificates expire

So I had a Draft about this last week but an usure feeling. I thought: “Do I really have anything to contribute? Folks are already aware of this. What can I really add?” So, I let it slide, then Thurday came and there was a hiccup: Apple hadn’t refreshed all their packages! Oh noes. Could this have been something my script could have helped head off? No but it might have made examining the packages Thursday afternoon a bit easier. So with that, I present certChecker.command

I’d advise just copy pasting the raw script into a new BBEdit document and saving it as “certChecker.command“. The extension matters, BBEdit will set the executable bit and you won’t have to mess with cleaning off the com.apple.quaratine flag as you would if you downloaded it.

Not much of a looker at the command line but comes together nicely in Quick Look

The need to find expired packages is critical if you use Jamf Pro to deploy your packages. macOS will throw an error if you try and install a pkg with an expired cert via the installer command line tool. It will suggest you use the -allowUntrusted flag, however this is not an option with Jamf Pro. You either have to get a new resigned package or repack it. Repacking is basically expanding the pacakge then flattening it again. This will strip out all certs. repackPKGs.command is useful for when vendors have forgotten to issue new packages and you need a working package.

Cert validation caveat: some packages can expire yet remain valid! These are signed with “trusted time stamps” and Suspicious Package explains this quite well. Their tool can better help you assess what a package will do when it’s expiration occurs. For certChecker.command I use pkgutil’s assesment for package files but for apps all we have is the the “not after” date.

Speaking of apps: the Install macOS Mojave.app from the App Store was giving me the “damaged” message on Thursday around 1PM CST…

The application certs were all VALID, my script said so, what gives? Doing a bit of sleuthing revealed InstallESD.dmg to be different between the two installers. I used find to run a md5 on all the files in each installer and send the output to two files. Running find from inside the apps keeps the base paths the same and allows for easy comparison with diff or XCode’s FileMerge (a favorite).

#compare two apps in Terminal
cd <ye olde installer app>
find . -type f -exec md5 {} \; | sort > ~/Desktop/YE_OLDE.txt
cd <new installer app>
find . -type f -exec md5 {} \; | sort > ~/Desktop/NEWNESS.txt
cd ~/Desktop
diff YE_OLDE.txt NEWNESS.txt

FileMerge inside XCode.app is a great visual diff’er
Turns out we have some stowaways in the old installer.
All is well, app cert and InstallESD packages are looking good.

By ~3pm CST they’d gotten everything fixed and the packages inside were all good. Not since the great expiration of 2015, have we had to care about expiring Apple packages. This time Apple has only pushed the app certs out 1 1/2 years to April 12th, 2021. That’s not long! The packages inside InstallESD.dmg are good however until April 14, 2029. Which one will win? Will we care (will we be able to roll back?) I’ll leave that as an exercise/rhetorical question for someone else.

In the meantime you might have other packages lurking in your distribution points that need updating or repacking. If so give certChecker.command a whirl to ferret them out. I hope it saves you some time and effort <insert reference to Roy Batty and “tears in the rain here” :>

macOS shell games: long live bash

TL;DR – Bash ain’t goin’ nowhere on Mac, both version-wise and in terms of its presence. Looking at the longevity of other shells on the system, it will likely be around for a good while longer.

There’s been a lot of hand wringing and angst online about bash and zsh becoming the new default shell. Some folks feel Apple is signaling deprecation and removal and have the crushing feeling they must convert all their bash script to zsh. I think that’s a bit unnecessary.

True, the default shell is changing from bash to zsh, as Apple notes here. This is indeed a Good Thing™ as zsh shell has been one of the most frequently updated shells on macOS. Bash, on the other hand, has been stuck at varying versions of 3.2 for 12 years now! On the plus side, sysadmins have “enjoyed” predictable and stable behavior from bash during this time. Sure, you’d love new features but when you are scripting for the enterprise, across multiple OS versions, this is just the sort of thing you want: boringness and dependability.

As far as deprecations go, the only thing Apple has signaled as being deprecated eventually are scripting language runtimes (not shells):

Scripting language runtimes such as Python, Ruby, and Perl are included in macOS for compatibility with legacy software. Future versions of macOS won’t include scripting language runtimes by default, and might require you to install additional packages. If your software depends on scripting languages, it’s recommended that you bundle the runtime within the app. (49764202)

Use of Python 2.7 isn’t recommended as this version is included in macOS for compatibility with legacy software. Future versions of macOS won’t include Python 2.7. Instead, it’s recommended that you run python3 from within Terminal. (51097165)

mac OS Catalina 10.15 Release Notes

I’ve done some digging and culled the shell versions from OS X 10.0 to macOS 10.15, along with their respective release dates. I think it shows that shells, no matter how old and crusty, tend to be long lived and not soon removed on macOS.

Here’s a quick way to check your shell versions (except for dash):

macOSzshbash/shcsh/tcshkshdash
10.03.0.8 (2000-05-16)3.0.8 (zsh, no bash)6.08.00 (1998-10-02)
10.13.0.8 (2000-05-16)3.0.8 (zsh, no bash)6.10.00 (2000-11-19)
10.24.0.4 (2001-10-26)2.05b.0 (2002-07-17)6.10.00 (2000-11-19)
10.34.1.1 (2003-06-19)2.05b.0 (2002-07-17)6.12.00 (2002-07-23)
10.44.2.3 (2005-03-00)2.05b.0 (2002-07-17)6.12.00 (2002-07-23)M p (1993-12-28)
10.54.3.4 (2007-04-19)3.2.17 (2007-05-01)6.14.00 (2005-03-23)M s+ (1993-12-28)
10.64.3.4 (2008-11-03)3.2.48 (2008-11-18)6.15.00 (2007-03-03)M s+ (1993-12-28)
10.74.3.11 (2010-12-20)3.2.48 (2008-11-18)6.17.00 (2009-07-10)M s+ (1993-12-28)
10.84.3.11 (2010-12-20)3.2.48 (2008-11-18)6.17.00 (2009-07-10)JM 93u (2011-02-08)
10.95.0.2 (2012-12-12)3.2.51 (2010-03-17)6.17.00 (2009-07-10)JM 93u (2011-02-08)
10.105.0.5 (2014-01-06)3.2.57 (2014-11-07)6.17.00 (2009-07-10)AJM 93u+ (2012-08-01)
10.115.0.8 (2015-05-31)3.2.57 (2014-11-07)6.18.01 (2012-02-14)AJM 93u+ (2012-08-01)
10.125.2 (2015-12-02)3.2.57 (2014-11-07)6.18.01 (2012-02-14)AJM 93u+ (2012-08-01)
10.135.3 (2016-12-12)3.2.57 (2014-11-07)6.18.01 (2012-02-14)AJM 93u+ (2012-08-01)
10.145.3 (2016-12-12)3.2.57 (2014-11-07)6.18.01 (2012-02-14)AJM 93u+ (2012-08-01)
10.155.7.1 (2019-02-03)3.2.57 (2014-11-07)6.21.00 (2019-05-08)AJM 93u+ (2012-08-01)dash-9 (1993)

As you can see, zsh has has been updated with almost every new release of macOS. Bash really hit a wall with 3.2 and as many have noted, it was v4’s change in licensing to GPLv3 that caused this (sh is really bash in sh compatibility mode so the versions are intertwined). csh/tcsh has the same duality thing going on and took a notably giant 7 year leap in 10.15 to a version from 2019. ksh has remained at the same version just as long as bash yet I don’t think anyone is fretting that ksh will be deprecated or removed. Finally, dash is just a weirdo that apparently disdains versioning! I used a combination of what /bin/dash and man dash to get some sort of crude answer.

So there you go: In my opinion, all signs point to bash being yet another shell on macOS for some time. Removing bash from macOS would break a lot of stuff and while that reason alone hasn’t stopped Apple before, I think they will let sleeping dogs lie. Go ahead and learn zsh, master it, customize it, or make it “sexy” but take the rumors of its demise on macOS with a grain of salt and dose of skepticism.

Determining the current console user in macOS

There’s a few methods floating out on the web, but I’d just like to point out a quick and reliable way to get the current console user on macOS using stat. This works great with Fast User Switching and if the mac is at the login screen it will return root as the user

consoleUser=$(stat -f %Su /dev/console)

There you go! Now go forth and script.

Also, if you are using backticks ` to capture output (a.k.a. command substitution) then consider using the more modern and nest-able $(…) method, here’s a good reason why: Why is $(…) preferred over `…` (backticks)?

Apple’s September 12th “Gather Round” event: Wild Unsubstantiated Speculation

Tomorrow Apple will announce some product updates for iPhone, iPad, and perhaps Mac.

The following is some unsubstantiated speculation:

  • USB-C will be announced as the standard connector on all Apple devices.
  • Macs be able charge iPads and iPhone via USB-C and vice versa.
  • Macs will also be able to harness the GPUs of iPads and iPhones using the USB-C connection: eGPU to go!

Now, in all reality I think they’ll hang onto lightning a little more until USB-C saturation is higher… then they’ll opt for USB-C2 😂. The eGPU idea is DOA I’m sure due to thermal issues and battery life of the iDevices. Anyway, just in case it happens: I told you so! ;)

How to determine if your Mac has a T2 chip

Do you know if your MacBook Pro has a T2 chip in it?
Here’s an easy way to tell:

Goto Identify your MacBook Pro model

Then look for the the murderous autonomous robot. Easy!

You can also run this:

/usr/libexec/PlistBuddy -c "print :0:_items:0:ibridge_model_name" /dev/stdin 2>/dev/null <<< "$(/usr/sbin/system_profiler -xml SPiBridgeDataType -nospawn)"

<<< – is an über cool “here string”

PlistBuddy is great at parsing data defaults might balk at, it can also take /dev/stdin!

Install macOS High Sierra, HFS Compression, and OS X 10.8

If you have downloaded Install macOS High Sierra.app on a non-macOS 10.8 machine then copy said installer to a 10.8 Mac, the installer will be unusable. Why? HFS Compression. It seems Install macOS High Sierra.app uses HFS compression on numerous files and it seems 10.8 has issues with that and will not “see” those files.

To quickly demonstrate which files are compressed, we will use stat and examine the st_flags attribute, 0=no compression, 32=compression (thanks ghost of Mac OS X Hints!)

IFS=$'\n\t'; for file in $(find /Applications/Install\ macOS\ High\ Sierra.app -type f); do echo "$(stat -f %f "$file"): $file)"; done

You’ll see many files with 32 as the flag, these will not be readable in 10.8

The trick is to copy the file and do away with the HFS compression, we can use ditto for this:

ditto --nopreserveHFSCompression /Applications/Install\ macOS\ High\ Sierra.app [destination folder]

This will produce an installer compatible with 10.8… sure you could have downloaded it via the Mac App Store by now on a 10.8 machine, but now you know.

Nothing (bash style)

The brunerd blog has been a whole lot of nothing lately, so let’s commemorate and celebrate with an entry featuring the premiere of the bash tag and category… hmm, which one is more useful? We’ll find out. Now as for nothing, there’s a legit command, special built-in to do nothing in bash!

man page for bash command :

: [arguments]

No effect; the command does nothing beyond expanding arguments and performing any specified redirections.  A zero exit code is returned.

 

Isn’t that lovely? When you need to do nothing, you can call :
Perhaps you are writing a script and aren’t sure what you’ll do for that if statement —

if [ "${this}" == "that" ]; then
#actually not sure what to do here, let's do nothing
:
else
echo "This else, I'll do"
fi

I made a gist here and I think I’ll keep making more. I’ll feature them here with the bash tag, if only as an auxillary backup of my brain and to add to the collective patchwork quilt of code we all use to get our ideas off the ground, when our reach is just a hare shy of grasp and we need a little help.

Also in the gist was a snippet of a novel use by kbeck at Extensis in his UTC removal script to use : to redirect a here document into itself and server as a comment block that doesn’t need # on every line to be treated as a comment —

: <<COMMENTBLOCK

[ ] 2016-0324: enclose me; love me. i am a block of comments

COMMENTBLOCK

Spiffy!

Java 8 Update 40 Installer App Fun!

So perhaps you saw my previous post: Java 8 without the Adware (aka Java8Unjunker)?

Java 8 U40 App

Good stuff eh? There was something in there that got me thinking: If they didn’t sign the package, is the app doing any integrity checks on the package inside either? Hmmm let’s see…

Voice over: We’ve secretly replaced the JavaAppletPlugin.pkg package with QuickTime 7 let’s see if it can tell the difference!
Not Java

Here we go!
Sure let me authenticate right when you run before any confirmation of action – why not!? (Ugh, bad form already.)

Java8 Auth

Safe and Easy

Oh OK, “safe and easy” – I love it! But just to clarify…
By “easy” you mean: Checking lots of trust boxes and clicking “Run” buttons a lot to get a Java apps working (plus crossing your fingers)?
By “safe” you mean: a steady stream of high scored CVEs with low complexity? Or even running in Unsafe Mode when needed?

OK what’s next?

Ask

Oh dear God no! No Ask.com. UncheckNext.

Oh, right, away we go, I gave you my password at the door. Installing Java are we?
Java8 InstallingInstalled

OK I’ve successfully installed Java then if you say so… I guess I that’s proof alright!
It then takes you to the Verify Java page — but who cares about that!

What does /var/log/install.log say about what was installed?

QT7 install Java8

 

Yep it installed the QuickTime7 package we put in there and Java Updater 40.app was none the wiser.

So in conclusion… That’s a really nifty “Ask Toolbar installer” with arbitrary package installer Oracle. It’s also a great delivery vehicle for malware by nefarious folks. Heck, bundle Java along with your Trojan and the “Verify Java” page would open too! Sheesh. Is the Ask contract that lucrative? Oracle made $38 billion in revenue last year, IAC the parent of Ask.com pulled in $3 billion. I guess IAC have got money to spend and Oracle will take it (but not invest in more secure installers?)

Notes: The first attempt used a QuickTimePlayer7.6.6_SnowLeopard.pkg with an expired certificate, that halted the install. The 2nd attempt I stripped out the expired certificate. It worked. The 3rd time I downloaded a newly signed version from Apple, that too worked.

Parting note for Oracle:
Sign your critical packages! If you insist on using your glorified “Ask Toolbar installer app” to do this, then require that it verify the package integrity in some way, Orable! (heh, that was a typo but I like it: Orable, ha!)

Open JavaAppletPluginJava8 No Lock

 

Update: Oracle is now signing the package within and the installer can no longer be duped into running an arbitrary package. The version when this article was written was 1.8.40.25, it is now 1.8.40.27.

Java 8 Signed
It’s signed now!

 

Damaged Java 8
Attempted JavaAppletPlugin.pkg Replacement

 

Java 8 without the Adware (aka Java8Unjunker)

So you’ve heard the Ask toolbar is now bundled with Java 8 Update 40 for the Mac?
Yep, apparently it is.

Ask

Fortunately there’s a simple workaround! Let’s take control of our Macs and do a little spelunking into this new installer app.

Right or Control-Click the Java 8 Update xx.app and choose Show Package Contents

Show Package Contents

Navigate into Contents then Resources folder
Eureka we’ve found it: JavaAppletPlugin.pkg
JavaAppletPlugin_LocationLet’s run it!

Gatekeeper_Java8

Aw snap. It seems the package isn’t signed and Gatekeeper is not happy about that. I’m flabbergasted that they’d sign the installer app but not the package inside? (Update: I’m really flabbergasted!)

Control or right-click on JavaAppletPlugin.pkg and choose Open

Java 8 PKG Open

Click Open

Open JavaAppletPlugin

Here we are. Your unsigned Java installer awaits.

Installer

Alternately… Java8Unjunker.command

script I just made to do the same thing plus some other nice things like: name the package and un-quarantine it. Of course being a script it’s not signable! Gatekeeper will balk if it’s on. You’ll need to right-click and choose Open as before.

Shell

Drag in your Java 8 Updater xx.app

Unjunker1

Press Enter.
Voilà! A folder with your package ready to double-click and go.

Unjunker2

Enjoy.

TMI…

#!/bin/bash

#Java 8 Unjunker - Joel Bruner
#Simply moves the JavaAppletPlugin.pkg package out of the installer app (which installs the Ask Toolbar) to the Desktop, renames and Un-Quarantines it

#touch file for debugging
[ -f /tmp/debug ] && set -x

#take command line argument too
sourceApp="$1"

#check to see if path provided is present and valid
#otherwise get the path
while [ -z "$sourceApp" -o ! -d "$sourceApp" ]; do
echo -n "Drag in Java 8 Update xx.app and press enter: "
read sourceApp
done

#get the version from the app
sourcePKGVersion=$(defaults read "$sourceApp"/Contents/Info CFBundleVersion)

#make Desktop folder and copy pkg to it, renamed
echo "Creating Directory ~/Desktop/Java $sourcePKGVersion"
mkdir ~/Desktop/"Java $sourcePKGVersion"
echo "Copying JavaAppletPlugin.pkg to ~/Desktop/Java $sourcePKGVersion/JavaAppletPlugin_${sourcePKGVersion}.pkg"
cp "$sourceApp"/Contents/Resources/JavaAppletPlugin.pkg ~/Desktop/"Java $sourcePKGVersion"/JavaAppletPlugin_${sourcePKGVersion}.pkg

#since Oracle doesn't sign the pkg just the .app we need to strip the quarantine xa off to suppress the warning
xattr -d com.apple.quarantine ~/Desktop/"Java $sourcePKGVersion"/JavaAppletPlugin_${sourcePKGVersion}.pkg

echo "Java Unjunked. Opening Folder."
open ~/Desktop/"Java $sourcePKGVersion"