diff --git a/make/projects-dir.mk b/make/projects-dir.mk index 683570b9..dc616693 100644 --- a/make/projects-dir.mk +++ b/make/projects-dir.mk @@ -397,8 +397,8 @@ git-commit: # --- rules -$(SSH_WRAPPER_SH): $(PROJECTS_MAKEFILE_NAME) - /bin/echo -e '#!/bin/bash $(SSH_WRAPPER_TRACE)\n\nexec /usr/bin/ssh $$JW_PKG_SSH_EXTRA_OPTS "$$@"' > $@.tmp +$(SSH_WRAPPER_SH): $(JWB_SCRIPT_DIR)/ssh-wrapper.sh + cp $< $@.tmp chmod 700 $@.tmp mv $@.tmp $@ ssh-wrapper: $(SSH_WRAPPER_SH) diff --git a/scripts/ssh-wrapper.sh b/scripts/ssh-wrapper.sh new file mode 100755 index 00000000..81ce686b --- /dev/null +++ b/scripts/ssh-wrapper.sh @@ -0,0 +1,62 @@ +#!/bin/bash + +# JW_PKG_SSH_EXTRA_OPTS in the context of CI can contain "-l someuser". For +# the ssh login to a remote ssh://otheruser@gitserver.com, this runs the ssh +# command "ssh -l someuser otheruser@gitserver.com". Since with openssh, -l +# takes precedence of the @, ssh tries to authenticate as someuser against +# gitserver, and is rightly denied access. +# +# That case happens with the janware's pub remote, so the -l needs to be +# removed from JW_PKG_SSH_EXTRA_OPTS if a remote with a username@ prefix from +# the Git configuration hits this script, and that's what most of its logic +# does. + +run_ssh() +{ + local has_user_at_host=0 + local arg + for arg in "$@"; do + case "$arg" in + -*) + ;; + ?*@?*) + has_user_at_host=1 + break + ;; + esac + done + + local -a extra_opts + read -r -a extra_opts <<< "${JW_PKG_SSH_EXTRA_OPTS:-}" + + if (( has_user_at_host )); then + local -a filtered_opts=() + local skip_next=0 + local opt + for opt in "${extra_opts[@]}"; do + if (( skip_next )); then + skip_next=0 + continue + fi + + case "$opt" in + -l) + skip_next=1 + ;; + -l?*) + ;; + *) + filtered_opts+=("$opt") + ;; + esac + done + + extra_opts=("${filtered_opts[@]}") + fi + + [[ "${JW_PKG_VERBOSE:-false}" = "true" ]] && set -x + + exec /usr/bin/ssh "${extra_opts[@]}" "$@" +} + +run_ssh "$@"