Automating automatic login for macOS

https://www.brunerd.com/blog/2021/08/24/automating-automatic-login-for-macos/

 

I recently had some Zoom Room Macs that needed some automation love and I thought I’d share how you can enable Automatic Login via script, perhaps you have several dozen and use Jamf or some other Mac management tool? Interested? Read on! Currently what’s out there are either standalone encoders only or part of larger packaging workflow to create a new user. The standalone encoders lacked some niceties like logging or account password verification and the package method added the required dependency of packaging if any changes were required. Above all, every script required Python, perl or Ruby, which are all on Apple’s hit list for removal in an upcoming OS release. For now macOS Monterey still has all of these runtimes but there will come a day when macOS won’t and will you really want to add 3rd party scripting runtimes and weaken your security by increasing attack surface when you can weaken your security using just shell? 😜 So for some fun, I re-implemented the /etc/kcpasswordencoder in shell so it requires only awk, sed, and xxd, all out of the box installs. I also added some bells and whistles too.

Some of the features are:

  • If the username is empty, it will fully disable Automatic Login. Since turning it off via the System Preferences GUI does not remove the /etc/kcpassword file if it has been enabled (!)
  • Ensures the specified user exists
  • Verifies the password is valid for the specified user
  • Can handle blank passwords
  • Works on OS X 10.5+ including macOS 12 Monterey

For the Jamf admin the script is setAutomaticLogin.jamf.sh and for standalone usage get setAutomaticLogin.sh, both take a username and password, in that order and then enable Automatic Login if it all checks out. The difference with the Jamf script is that the first parameter is ${3} versus ${1} for the standalone version.

Also here’s a well commented Gist as a little show and tell for what the shell only version of the kcpassword encoder looks like. Enjoy!

 

  #!/bin/bash
  #kcpasswordEncode Copyright (c) 2021 Joel Bruner (https://github.com/brunerd)
  #Licensed under the MIT License
   
  #given a string creates data for /etc/kcpassword
  function kcpasswordEncode {
   
  #ascii string
  local thisString="${1}"
  local i
   
  #converted to hex representation with spaces
  local thisStringHex_array=( $(echo -n "${thisString}" | xxd -p -u | sed 's/../& /g') )
   
  #macOS cipher hex ascii representation array
  local cipherHex_array=( 7D 89 52 23 D2 BC DD EA A3 B9 1F )
   
  #cycle through each element of the array
  for ((i=0; i < ${#thisStringHex_array[@]}; i++)); do
  #use modulus to loop through the cipher array elements
  local charHex_cipher=${cipherHex_array[$(( $i % 11 ))]}
   
  #get the current hex representation element
  local charHex=${thisStringHex_array[$i]}
   
  #use $(( shell Aritmethic )) to ^ xor the two 0x-prepended hex values to decimal (ugh)
  #then printf to convert to two char hex value
  #use xxd to encode to actual value and append to the encodedString variable
  local encodedString+=$(printf "%02X" "$(( 0x${charHex_cipher} ^ 0x${charHex} ))" | xxd -r -p)
  done
   
  #under 12 get padding by subtraction
  if [ "${#thisStringHex_array[@]}" -lt 12 ]; then
  local padding=$(( 12 - ${#thisStringHex_array[@]} ))
  #over 12 get padding by subtracting remainder of modulo 12
  elif [ "$(( ${#thisStringHex_array[@]} % 12 ))" -ne 0 ]; then
  local padding=$(( (12 - ${#thisStringHex_array[@]} % 12) ))
  #no padding needed
  else
  local padding=0
  fi
   
   
  #pad the end so length is multiple of 12
  local j
  for ((j=0; j < ${padding}; j++, i++)); do
  #get current cipher character
  charHex_cipher=${cipherHex_array[$(( $i % 11 ))]}
   
  #add the cipher to the end as padding
  encodedString+=$(printf "%02X" "0x${charHex_cipher}" | xxd -r -p)
  done
   
  #return the string without a newline
  echo -n "${encodedString}"
  }
   
  #this just echoes it out use, does not write the file nor enable plist (see my setAutoLogin for that)
  kcpasswordEncode "${1}"

 

Update: I meant to expound on how it didn’t seem that padding kcpassword to a length multiple of 12 was necessary, since it had been working fine on the versions I was testing with but then I tested on Catalina (thinking of this thread) and was proven wrong by Catalina. I then padded with 0x00 with HexFiend in a successful test but was reminded that bash can’t handle that character in strings, instead I padded with 0x01, which worked on some macOS versions but not others. Finally, I settled on doing on what macOS does somewhat, whereas it pads with the next cipher character then seemingly random data, I pad with the cipher characters for the length of the padding. This works for Catalina and other of macOS versions. 😅

Cet article vous a-t-il été utile ?
Utilisateurs qui ont trouvé cela utile : 0 sur 0
Vous avez d’autres questions ? Envoyer une demande

0 Commentaires

Vous devez vous connecter pour laisser un commentaire.
Réalisé par Zendesk