3

I have an ssh box that runs Subversion and Mercurial services. On connection to this box, a script verifies that the user is only running mercurial or svn related commands:

    #!/bin/bash
    #
    # Verify that the requested command is an svnserve call.
    #
    # Note that sshd stores the command requested by the client in
    # the variable "SSH_ORIGINAL_COMMAND".

    echo $SSH_ORIGINAL_COMMAND | grep -E '^hg -R'
    ISHG=$?

    if [[ $SSH_ORIGINAL_COMMAND = "svnserve -t" || $ISHG -eq 0 ]]
    then
            exec $SSH_ORIGINAL_COMMAND
    else
            echo "You are only allowed svn access to this server."
    fi

The problem is, hg verification is not very clean or secure. If I include backticks in my remote ssh command, the "echo $SSH_ORIGINAL_COMMAND" line will happily execute it. Does anyone have any suggestions for cleaning this up a little bit?

Thanks!

EightyEight
  • 303
  • 1
  • 2
  • 11
  • Cannot reproduce in bash 4.1.5 - backticks are preserved by `exec $var`. (By the way, `[[` can do regex matching with `=~`.) – user1686 Feb 01 '11 at 18:44
  • I think the first ECHO, where I pipe it into grep is the culprit. I had issues with =~, I should try it again! – EightyEight Feb 01 '11 at 18:51

2 Answers2

4

Yeah. Don't use shell for that. Write a program in a language that would allow you to make sure that the only binaries it's going to execute are white-listed.

poige
  • 9,448
  • 2
  • 25
  • 52
2

Mercurial comes with a tool for exactly this! Use the contrib/hg-ssh script we provide to restrict the commands. The file contains this header to explain how to use it:

To be used in ~/.ssh/authorized_keys with the command option, see sshd(8):

command="hg-ssh path/to/repo1 /path/to/repo2 ~/repo3 ~user/repo4" ssh-dss ...

(probably together with these other useful options: no-port-forwarding, no-X11-forwarding, no-agent-forwarding)

This allows pull/push over SSH from/to the repositories given as arguments. If all your repositories are subdirectories of a common directory, you can allow shorter paths with:

command="cd path/to/my/repositories && hg-ssh repo1 subdir/repo2"

You can use pattern matching of your normal shell, e.g.:

command="cd repos && hg-ssh user/thomas/* projects/{mercurial,foo}" 
Martin Geisler
  • 1,271
  • 9
  • 23