If I disable git-shell's interactive mode by removing the
~/git-shell-commands directory, then attempts to use 'ssh' with the
git account interactively produce an error message intended for the

        $ ssh git@myserver
        fatal: Interactive git shell is not enabled.
        hint: ~/git-shell-commands should exist and have read and execute 

That is helpful for the new admin who is wondering "What? Why isn't
the git-shell I just set up working?", but once the site setup is
finished, it is better to give the user a friendly hint that she is on
the right track, like GitHub does:

        Hi <username>! You've successfully authenticated, but
        GitHub does not provide shell access.

An appropriate greeting might even include more complex information,
like a list of repositories the user has access to.  If the
git-shell-commands directory exists and contains a "help" script, we
already run it when the shell is run without any commands, giving the
server a chance to provide a custom message.  Unfortunately, the
presence of the git-shell-commands directory means we also enter an
interactive mode, prompting and accepting commands (of which there may
be none) from the user, which many servers would not want.  To solve
this, we abort the interactive shell on a non-zero exit code from the
"help" script.  This lets the server say whatever it likes, and then
hang up.

Downside: this will prevent interactive git-shell logins in existing
setups where the "help" script exits with nonzero status by mistake.
Hopefully those are rare enough to not cause much trouble in practice.

Reported-by: Ethan Reesor <firelizz...@gmail.com>
Signed-off-by: Jonathan Nieder <jrnie...@gmail.com>
Improved-by: Jeff King <p...@peff.net>
 Documentation/git-shell.txt | 20 ++++++++++++++++++++
 shell.c                     | 10 ++++++++--
 2 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/Documentation/git-shell.txt b/Documentation/git-shell.txt
index 4fe93203..60051e63 100644
--- a/Documentation/git-shell.txt
+++ b/Documentation/git-shell.txt
@@ -59,6 +59,26 @@ users to list repositories they have access to, create, 
delete, or
 rename repositories, or change repository descriptions and
+If the `help` command exists and exits with nonzero status, the
+interactive shell is aborted.
+To disable interactive logins, displaying a greeting instead:
+$ chsh -s /usr/bin/git-shell
+$ mkdir $HOME/git-shell-commands
+$ cat >$HOME/git-shell-commands/help <<\EOF
+printf '%s\n' "Hi $USER! You've successfully authenticated, but I do not"
+printf '%s\n' "provide interactive shell access."
+exit 128
+$ chmod +x $HOME/git-shell-commands/help
diff --git a/shell.c b/shell.c
index 84b237fe..3abc2b84 100644
--- a/shell.c
+++ b/shell.c
@@ -63,10 +63,16 @@ static void cd_to_homedir(void)
 static void run_shell(void)
-       int done = 0;
+       int done = 0, status;
        static const char *help_argv[] = { HELP_COMMAND, NULL };
        /* Print help if enabled */
-       run_command_v_opt(help_argv, RUN_SILENT_EXEC_FAILURE);
+       status = run_command_v_opt(help_argv, RUN_SILENT_EXEC_FAILURE);
+       if (!status)
+               ; /* success */
+       else if (status == -1 && errno == ENOENT)
+               ; /* help disabled */
+       else
+               exit(status);
        do {
                struct strbuf line = STRBUF_INIT;

To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to