Skip to content

Instantly share code, notes, and snippets.

@bdurrow
Last active June 11, 2020 05:51
Show Gist options
  • Select an option

  • Save bdurrow/5873083ed4f8f52f50a22a240b5a2543 to your computer and use it in GitHub Desktop.

Select an option

Save bdurrow/5873083ed4f8f52f50a22a240b5a2543 to your computer and use it in GitHub Desktop.
kinit wrapper that supports pkinit to allow for 2FA (typically saved as /usr/local/bin/kinit)
#!/bin/bash
# (c) 2020 by I. S. Consulting, LLC use and remix allowed with attribution.
# Initially created by [bgdurrow]
# Available from https://gist.github.com/bdurrow/5873083ed4f8f52f50a22a240b5a2543
#I don't think that I have used any bash specific features other
#than these "strict mode" settings.
set -euo pipefail
IFS=$'\n\t'
function kinit() {
local OUR_ARGS=( "$@" )
#local KINIT="${0}" #or kinit
local KINIT="/usr/bin/kinit"
local KLIST_OUTPUT=""
local KLIST_TICKET_CACHE=""
local KLIST_DEFAULT_PRINCIPAL=""
local ANONYMOUS_PRINCIPAL="WELLKNOWN/ANONYMOUS@WELLKNOWN:ANONYMOUS"
local TRUE=0
local FALSE=1
function parse_klist_output() {
KLIST_TICKET_CACHE=$(printf '%s' "$KLIST_OUTPUT" | sed -nE 's/^.*\scache:\s+(.*)$/\1/p')
KLIST_DEFAULT_PRINCIPAL=$(printf '%s' "$KLIST_OUTPUT" | sed -nE 's/^Default principal:\s+(.*)$/\1/p')
}
function get_info_from_klist() {
if KLIST_OUTPUT=$(klist 2>/dev/null); then
parse_klist_output
fi
}
function principal_already_present() {
if [ "$#" -eq 0 ]; then
#No Args
return $FALSE;
elif [ "$#" -eq 1 ]; then
#Only one arg, has to be principal
return $TRUE;
else
#For two or more arguments it is more complicated,
#Look at the second to last argument and if that takes
#another argument then the last argument is not a principal
local SECOND_TO_LAST=$(echo $(eval "printf \"%s\n\" \"\$$(($#-1))\""));
case ${SECOND_TO_LAST} in
#SYNOPSIS
#kinit [-V] [-l lifetime] [-s start_time] [-r renewable_life] [-p | -P] [-f | -F] [-a] [-A] [-C] [-E] [-v] [-R]
#[-k [-t keytab_file]] [-c cache_name] [-n] [-S service_name] [-I input_ccache] [-T armor_ccache] [-X
#attribute[=value]] [principal]
-l|-s|-r|-k|-t|-c|-S|-I|-T|-X)
return $FALSE
;;
-V|-p|-P|-f|-F|-a|-A|-C|-E|-v|-R|-n)
return $TRUE
;;
-*)
echo "FATAL: unknown argument"
exit 1
;;
*)
return $TRUE
;;
esac
fi
}
function compute_principal() {
if principal_already_present $@; then
return
fi
if [ -n "${KLIST_DEFAULT_PRINCIPAL}" ]; then
if [ "${KLIST_DEFAULT_PRINCIPAL}" = "${ANONYMOUS_PRINCIPAL}" ]; then
printf "%s" "${USER}"
else
printf "%s" "${KLIST_DEFAULT_PRINCIPAL}"
fi
else
printf "%s" "${USER}"
fi
}
function arg_present() {
search_arg=$1; shift
for arg; do
if [ "${arg}" = "${search_arg}" ]; then
return $TRUE
fi
done
return $FALSE
}
#If pkinit isn't available this script isn't helpful
if ! [ -e /usr/lib*/krb5/plugins/preauth/pkinit.so ]; then
#Perhaps we should print a warning and suggest installing
#pkinit support, ie: yum -y krb5_pkinit
command $KINIT $@
return $?
fi
#Special case: if called with -n just run kinit as called
if arg_present "-n" $@; then
command $KINIT $@
return $?
fi
#Special case: if called with -T just run kinit as called
if arg_present "-T" $@; then
command $KINIT $@
return $?
fi
get_info_from_klist
#Set the PRINCIPAL, note this will be empty if the argument list appears to end with a principal
PRINCIPAL=$(compute_principal $@)
if [ -z "${KLIST_TICKET_CACHE}" ]; then
command $KINIT -n
#kinit -n adds an anonymous auth to the ticket cache
#it is a bit of a pain to have it there as it changes the default
#principal and will prevent kdestroy from operating with the expected
#behavior. We don't need it any more after we auth so we will set
#this cleanup operation.
function finish {
#Don't depend on the local variable for this :(
kdestroy -p "WELLKNOWN/ANONYMOUS@WELLKNOWN:ANONYMOUS"
}
trap finish EXIT
get_info_from_klist
#FATAL: If we still don't have a defined TICKET_CACHE
if [ -z "${KLIST_TICKET_CACHE}" ]; then
echo "FATAL: Could not setup Ticket Cache"
return 1
fi
fi
command $KINIT -T ${KLIST_TICKET_CACHE} $@ ${PRINCIPAL}
return $?
}
kinit $@
@bdurrow

bdurrow commented Jun 11, 2020

Copy link
Copy Markdown
Author

Feedback welcome!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment