Skip to content

Commit

Permalink
Merge branch 'prerel' into feat/custom_parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
zachmann committed Jul 10, 2024
2 parents 0cdb157 + c0a9f33 commit f7038c0
Show file tree
Hide file tree
Showing 4 changed files with 316 additions and 3 deletions.
20 changes: 17 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ GEN = oidc-gen
ADD = oidc-add
CLIENT = oidc-token
KEYCHAIN = oidc-keychain
TOKENSH = oidc-tokensh
AGENT_SERVICE = oidc-agent-service
PROMPT = oidc-prompt

Expand Down Expand Up @@ -334,6 +335,7 @@ endif
SIMPLECSS_FILE := $(shell CSS="/usr/share/simple.css/simple.min.css" && [ -f "$$CSS" ] || CSS="$(PROMPT_SRCDIR)/html/static/css/lib/simple.min.css" ; echo "$$CSS")
ifndef ANY_MSYS
KEYCHAIN_SOURCES := $(SRCDIR)/$(KEYCHAIN)/$(KEYCHAIN)
TOKENSH_SOURCES := $(SRCDIR)/$(TOKENSH)/$(TOKENSH)
AGENTSERVICE_SRCDIR := $(SRCDIR)/$(AGENT_SERVICE)
endif
endif
Expand Down Expand Up @@ -421,7 +423,7 @@ else
ifdef MINGW
build: shared_lib $(APILIB)/liboidc-agent.a
else
build: $(BINDIR)/$(AGENT) $(BINDIR)/$(GEN) $(BINDIR)/$(ADD) $(BINDIR)/$(CLIENT) $(BINDIR)/$(AGENT_SERVICE) $(BINDIR)/$(KEYCHAIN) $(BINDIR)/$(PROMPT)
build: $(BINDIR)/$(AGENT) $(BINDIR)/$(GEN) $(BINDIR)/$(ADD) $(BINDIR)/$(CLIENT) $(BINDIR)/$(AGENT_SERVICE) $(BINDIR)/$(KEYCHAIN) $(BINDIR)/$(TOKENSH) $(BINDIR)/$(PROMPT)
endif
endif

Expand Down Expand Up @@ -508,6 +510,10 @@ $(BINDIR)/$(KEYCHAIN): $(KEYCHAIN_SOURCES) $(BINDIR)
@cat $(KEYCHAIN_SOURCES) >$@ && chmod 755 $@
@echo "Building "$@" complete!"

$(BINDIR)/$(TOKENSH): $(TOKENSH_SOURCES) $(BINDIR)
@cat $(TOKENSH_SOURCES) >$@ && chmod 755 $@
@echo "Building "$@" complete!"

$(BINDIR)/$(AGENT_SERVICE): $(AGENTSERVICE_SRCDIR)/$(AGENT_SERVICE) $(AGENTSERVICE_SRCDIR)/options $(BINDIR)
@sed -n '/OIDC_INCLUDE/!p;//q' $< >$@
@sed 's!/etc/oidc-agent!$(CONFIG_AFTER_INST_PATH)/oidc-agent!' $(AGENTSERVICE_SRCDIR)/options | sed 's!/usr/bin/oidc-agent!$(BIN_AFTER_INST_PATH)/bin/$(AGENT)!' >>$@
Expand Down Expand Up @@ -541,15 +547,15 @@ endif

ifndef ANY_MSYS
.PHONY: install_bin
install_bin: $(BIN_PATH)/bin/$(AGENT) $(BIN_PATH)/bin/$(GEN) $(BIN_PATH)/bin/$(ADD) $(BIN_PATH)/bin/$(CLIENT) $(BIN_PATH)/bin/$(KEYCHAIN) $(BIN_PATH)/bin/$(AGENT_SERVICE) $(PROMPT_BIN_PATH)/bin/$(PROMPT)
install_bin: $(BIN_PATH)/bin/$(AGENT) $(BIN_PATH)/bin/$(GEN) $(BIN_PATH)/bin/$(ADD) $(BIN_PATH)/bin/$(CLIENT) $(BIN_PATH)/bin/$(KEYCHAIN) $(BIN_PATH)/bin/$(TOKENSH) $(BIN_PATH)/bin/$(AGENT_SERVICE) $(PROMPT_BIN_PATH)/bin/$(PROMPT)
@echo "Installed binaries"

.PHONY: install_conf
install_conf: $(CONFIG_PATH)/oidc-agent/$(PROVIDERCONFIGD) $(CONFIG_PATH)/oidc-agent/$(PROVIDERCONFIG) $(CONFIG_PATH)/oidc-agent/$(GLOBALCONFIG) $(CONFIG_PATH)/oidc-agent/$(SERVICECONFIG) $(TMPFILES_PATH)/oidc-agent.conf
@echo "Installed config files"

.PHONY: install_bash
install_bash: $(BASH_COMPLETION_PATH)/$(AGENT) $(BASH_COMPLETION_PATH)/$(GEN) $(BASH_COMPLETION_PATH)/$(ADD) $(BASH_COMPLETION_PATH)/$(CLIENT) $(BASH_COMPLETION_PATH)/$(AGENT_SERVICE) $(BASH_COMPLETION_PATH)/$(KEYCHAIN)
install_bash: $(BASH_COMPLETION_PATH)/$(AGENT) $(BASH_COMPLETION_PATH)/$(GEN) $(BASH_COMPLETION_PATH)/$(ADD) $(BASH_COMPLETION_PATH)/$(CLIENT) $(BASH_COMPLETION_PATH)/$(AGENT_SERVICE) $(BASH_COMPLETION_PATH)/$(KEYCHAIN) $(BASH_COMPLETION_PATH)/$(TOKENSH)
@echo "Installed bash completion"

.PHONY: install_man
Expand Down Expand Up @@ -650,6 +656,9 @@ $(BIN_PATH)/bin/$(CLIENT): $(BINDIR)/$(CLIENT) $(BIN_PATH)/bin
$(BIN_PATH)/bin/$(KEYCHAIN): $(BINDIR)/$(KEYCHAIN) $(BIN_PATH)/bin
@install -p $< $@

$(BIN_PATH)/bin/$(TOKENSH): $(BINDIR)/$(TOKENSH) $(BIN_PATH)/bin
@install -p $< $@

$(BIN_PATH)/bin/$(AGENT_SERVICE): $(BINDIR)/$(AGENT_SERVICE) $(BIN_PATH)/bin
@install -p $< $@

Expand Down Expand Up @@ -686,6 +695,9 @@ $(BASH_COMPLETION_PATH)/$(CLIENT): $(BASH_COMPLETION_PATH)
$(BASH_COMPLETION_PATH)/$(KEYCHAIN): $(BASH_COMPLETION_PATH)
@ln -s $(AGENT) $@

$(BASH_COMPLETION_PATH)/$(TOKENSH): $(BASH_COMPLETION_PATH)
@ln -s $(AGENT) $@

$(BASH_COMPLETION_PATH)/$(AGENT_SERVICE): $(CONFDIR)/bash-completion/oidc-agent-service $(BASH_COMPLETION_PATH)
@install -p -m 644 $< $@

Expand Down Expand Up @@ -777,6 +789,7 @@ uninstall_bin:
@$(rm) $(BIN_PATH)/bin/$(ADD)
@$(rm) $(BIN_PATH)/bin/$(CLIENT)
@$(rm) $(BIN_PATH)/bin/$(KEYCHAIN)
@$(rm) $(BIN_PATH)/bin/$(TOKENSH)
@$(rm) $(BIN_PATH)/bin/$(AGENT_SERVICE)
@$(rm) $(PROMPT_BIN_PATH)/bin/$(PROMPT)
@echo "Uninstalled binaries"
Expand Down Expand Up @@ -808,6 +821,7 @@ uninstall_bashcompletion:
@$(rm) $(BASH_COMPLETION_PATH)/$(AGENT)
@$(rm) $(BASH_COMPLETION_PATH)/$(AGENT_SERVICE)
@$(rm) $(BASH_COMPLETION_PATH)/$(KEYCHAIN)
@$(rm) $(BASH_COMPLETION_PATH)/$(TOKENSH)
@echo "Uninstalled bash completion"

endif
Expand Down
23 changes: 23 additions & 0 deletions gitbook/oidc-tokensh/general.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
## General Usage

`oidc-tokensh` is a tool to ensure that valid Access Tokens are always
available in a location such as `$XDG_RUNTIME_DIR/bt_u$ID`,
`/tmp/bt_u$ID`, or `$BEARER_TOKEN_FILE` just as specified
<https://zenodo.org/records/3937438>.

`oidc-tokensh` provides an "almost drop-in replacement" for `httokensh` of
the [htgettoken](https://github.com/fermitools/htgettoken) tool package.

`oidc-tokensh` starts a new shell through `oidc-agent` and prompts the user
for the passphrase of the `oidc-agent shortname` that will be loaded.

The user may specify the `shortname` with the `--oidc <shortname>` option.
If only one `shortname` is configured, this one will be used by default.

```
Usage: oidc-tokensh [--oidc <shortname>] [-- <command>]
```


See [Detailed Information About All
Options](options.md) for more information.
34 changes: 34 additions & 0 deletions gitbook/oidc-tokensh/options.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
## Detailed Information About All Options

* [`-h, --help`](#help)
* [`--oidc <name>|<OP-url>`](#oidc)
* [`--minsecs <seconds>`](#minsecs)
* [`-o|--outfile <file>`](#outfile)
* [`-v|--verbose`](#verbose)
* [`-- <command>`](#command)


### `--oidc`

This option is used to specify the `shortname` of an `oidc-agent`
configuration. If only one agent configuration is defined, this option may
be skipped.

### `--minsecs`

Specify the minimum number of seconds that the Access Token should still
be valid for.

### `--outfile`

Specify alternative file for storing the Access Token.

### `--verbose`

Show debug output

### `-- <command>`

Instead of the default shell, you can specify any other shell-like command
here. This is useful to specify your favourite shell.

242 changes: 242 additions & 0 deletions src/oidc-tokensh/oidc-tokensh
Original file line number Diff line number Diff line change
@@ -0,0 +1,242 @@
#!/bin/bash
#
# Run oidc-agent and then start a shell command and keep the access
# token updated for as long as the command runs.
#
# Adapted by Marcus Hardt 2024, based on httokensh by Dave Dykstra

usage()
{
echo "This tool is based on httokensh by Dave Dykstra."
echo ""
echo "Usage: oidc-tokensh [-h] [oidc-token options] -- [command]"
echo
echo "Runs oidc-agent and oidc-token with given options, starts the "
echo "command, and runs oidc-token in the background as needed to "
echo "renew the token until the command exits."
echo ""
echo "Options:"
echo " -h, --help show this help message and exit"
echo " --oidc <name>|<OP-url> name or url of the oidc-agent "
echo " configuration to use"
echo " --minsecs <seconds> minimum lifetime the token should have"
echo " -o|--outfile <file> specify alternative file for storing"
echo " the Access Token"
echo " -v|--verbose show debug output"
echo ""
echo "command defaults to \$SHELL"
} >&2

# if [ $# = 0 ] || [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
# echo "[${LINENO}] You ran: $0 $*"
# # usage
# fi

OIDC_TOKEN_ARGS=""
CMND_ARGS=""
ORIG_ARGS=""
GOTSEP=false
MINSECS=60
GOTVERBOSE=false
GOTOUTFILE=false
START_RENEWER=false

while [ $# -gt 0 ]; do
ORIG_ARGS="${ORIG_ARGS} ${1}"
if $GOTSEP; then
CMND_ARGS="${CMND_ARGS} ${1}"
else
case "$1" in
-h|--help) usage; exit 0 ;;
--) GOTSEP=true ;;
-v|--verbose) GOTVERBOSE=true ;;
--minsecs) MINSECS=$2; ORIG_ARGS="${ORIG_ARGS} $2"; shift ;;
-o|--outfile) GOTOUTFILE=true OUTFILE=$2; ORIG_ARGS="${ORIG_ARGS} $2"; shift ;;
--oidc) OIDC_ID=$2; ORIG_ARGS="${ORIG_ARGS} $2"; shift ;;
--renewer) START_RENEWER=true ;;
esac
fi
shift
done

#########################################################################
get_bearer_token_file(){
# Get BEARER_TOKEN_FILE according to WLCG Bearer Token Discovery (https://zenodo.org/records/3937438)
RETVAL=""
if [ -z "${BEARER_TOKEN_FILE}" ]; then
if [ -z "$XDG_RUNTIME_DIR" ]; then
RETVAL="/tmp/bt_u$(id -u)"
else
RETVAL="${XDG_RUNTIME_DIR}/bt_u$(id -u)"
fi
else
RETVAL="${BEARER_TOKEN_FILE}"
fi
echo "${RETVAL}"
}
get_bearer_token_file_orig(){
if [ -z "$BEARER_TOKEN_FILE" ] && ! $GOTOUTFILE; then
if [ -n "$XDG_RUNTIME_DIR" ]; then
BTFILE="bt_u$(id -u).sh-$$"
BEARER_TOKEN_FILE=$XDG_RUNTIME_DIR/$BTFILE
else
BEARER_TOKEN_FILE=/tmp/$BTFILE
fi
export BEARER_TOKEN_FILE
fi

if ${GOTOUTFILE}; then
export BEARER_TOKEN_FILE="${OUTFILE}"
fi
echo "[${LINENO}] ${BEARER_TOKEN_FILE}"
}

decodejwt() {
echo "$1" | cut -d. -f 2 \
| base64 -di 2>/dev/null \
| jq --indent 4 2>/dev/null
}

gettoken() {
MESSAGE="$1"
TIME_PARAM="$2"
[ "${GOTVERBOSE}" == "true" ] && [ "${START_RENEWER}" == "false" ] && {
echo "[${LINENO}] running oidc-add ${OIDC_TOKEN_ARGS}"
}
oidc-add ${OIDC_TOKEN_ARGS} >/dev/null
TOKEN=$(oidc-token ${OIDC_TOKEN_ARGS})
# TOKEN=$(oidc-token egi)
RETVAL="$?"
if [ $RETVAL != 0 ]; then
echo "[${LINENO}] oidc-token failed, ${MESSAGE}" >&2
exit $RETVAL
fi
echo "${TOKEN}" > "${BEARER_TOKEN_FILE}"

TOKENJSON=$(decodejwt "${TOKEN}")
RETVAL="$?"
if [ $RETVAL != 0 ]; then
echo "[${LINENO}] decodejwt failed, ${MESSAGE}" >&2
exit $RETVAL
fi

EXP=$(echo "${TOKENJSON}"|jq .exp)
NOW=$(date +%s)
SLEEPSECS=$((EXP - MINSECS - NOW + TIME_PARAM))
[ "${GOTVERBOSE}" == "true" ] && [ "${START_RENEWER}" == "false" ] && {
echo "[${LINENO}] SLEEPSECS: ${SLEEPSECS} -- TIME_PARAM: ${TIME_PARAM}"
}
if [ "${SLEEPSECS}" -lt "${TIME_PARAM}" ]; then
echo "[${LINENO}] Calculated renewal time of $SLEEPSECS seconds is less than ${TIME_PARAM}, ${MESSAGE}"
exit 1
fi
}

start_agent() {
[ "${GOTVERBOSE}" == "true" ] && [ "${START_RENEWER}" == "false" ] && {
echo "[${LINENO}] starting: >>oidc-agent -- /bin/bash -c "$0 --renewer ${ORIG_ARGS}"<<"
}
oidc-agent -- /bin/bash -c "$0 --renewer ${ORIG_ARGS}"
}

start_token_renewer() {
# enable job control so background processes get their own process group
gettoken "Initial" 20
set -m
{
exec 3>&1 1>>"$BEARER_TOKEN_FILE.log"
exec 4>&2 2>>"$BEARER_TOKEN_FILE.log"
trap cleanup 0
# keep a copy of $PPID because it will change to 1 if parent dies
PARENTPID=$PPID
[ "${GOTVERBOSE}" == "true" ] && {
echo "[${LINENO}] oidc-token args are ${OIDC_TOKEN_ARGS}"
}
while true; do
echo "Renewal scheduled in $SLEEPSECS seconds"
sleep $SLEEPSECS
date
if kill -0 $PARENTPID 2>/dev/null; then
gettoken "Regular" 60
else
echo "[${LINENO}] Parent process $PARENTPID not running, exiting"
echo "[${LINENO}] mypid: $$"
exit 0
fi
done
} &
export BACKGROUND_PID=$!
[ "${GOTVERBOSE}" == "true" ] && [ "${START_RENEWER}" == "false" ] && {
echo "[${LINENO}] excuting: ${CMND_ARGS}"
}
# Start the actual shell
${CMND_ARGS}

}

cleanup()
{
[ -z "${BACKGROUND_PID}" ] || {
if kill -0 "$BACKGROUND_PID" 2>/dev/null; then
rm -f "${BEARER_TOKEN_FILE}" "${BEARER_TOKEN_FILE}.log"
else
echo -e "\n\nRenewal background process failed to renew Access Token, see $BEARER_TOKEN_FILE.log\n"
echo "Renewal background process failed, see $BEARER_TOKEN_FILE.log" >> "${BEARER_TOKEN_FILE}.log"
exit 2
fi
}
}
#########################################################################

[ -z "${OIDC_ID}" ] && { # the --oidc option was not defined. We try to find
# if there is only one configured. If so, we use
# that one.
echo "Trying to auto-detect oidc-agent configuration"
NUM_OIDC_ACCOUNTS=$(oidc-add -l | grep -cv "The following")
[ "$NUM_OIDC_ACCOUNTS" -eq 1 ] && {
OIDC_ID=$(oidc-add -l | grep -v "The following")
echo "Defaulting to $OIDC_ID"
}
[ "$NUM_OIDC_ACCOUNTS" -eq 1 ] || {
echo "Please specify the oidc-agent shortname that you wish to use"
exit 3
}
}

OIDC_TOKEN_ARGS="${OIDC_ID} -t ${MINSECS}"
[ "${GOTVERBOSE}" == "true" ] && [ "${START_RENEWER}" == "false" ] && {
echo "[${LINENO}] OIDC_TOKEN_ARGS: ${OIDC_TOKEN_ARGS}"
}

if ! $GOTSEP; then
CMND_ARGS="${SHELL}"
fi

BEARER_TOKEN_FILE=$(get_bearer_token_file)
export BEARER_TOKEN_FILE


[ "${GOTVERBOSE}" == "true" ] && [ "${START_RENEWER}" == "false" ] && {
echo "[${LINENO}] Bearer Token is at $BEARER_TOKEN_FILE"
}
[ "${START_RENEWER}" == "false" ] && {
echo "Renewal log is at $BEARER_TOKEN_FILE.log"
}

[ "${START_RENEWER}" == "true" ] && {
[ "${GOTVERBOSE}" == "true" ] && [ "${START_RENEWER}" == "false" ] && {
echo "[${LINENO}] Starting renewer"
echo "[${LINENO}] OIDC_TOKEN_ARGS: ${OIDC_TOKEN_ARGS}"
}
trap cleanup 0
start_token_renewer
[ "${GOTVERBOSE}" == "true" ] && [ "${START_RENEWER}" == "false" ] && {
echo "[${LINENO}] BACKGROUND_PID: ${BACKGROUND_PID}"
}
}


[ "${START_RENEWER}" == "false" ] && {
# trap cleanup 0
start_agent
}

0 comments on commit f7038c0

Please sign in to comment.