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!

link|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
feedback

2 Answers

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.

link|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
feedback

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

Your Answer

 
or
required, but never shown

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