Server Fault is a question and answer site for system and network administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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:

    # 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'

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

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?


share|improve this question
Cannot reproduce in bash 4.1.5 - backticks are preserved by exec $var. (By the way, [[ can do regex matching with =~.) – grawity Feb 1 '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 1 '11 at 18:51
up vote 4 down vote accepted

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.

share|improve this answer
Seems like too much work to break out a C compiler for this.. – EightyEight Feb 1 '11 at 18:41
Is Perl prohibited at your site? :) – poige Feb 1 '11 at 18:46
@EightyEight: Nobody mentioned C. – grawity Feb 1 '11 at 18:48
@EightyEight Perl (IPC modules) or Python (subprocess) should both be pretty capable for this kind of thing. – EvanK Feb 1 '11 at 18:49
Ah fair enough, perl it is. I'll try grawity's Bash =~ suggestion first though. – EightyEight Feb 1 '11 at 18:53

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}" 
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.