Re: [PATCHv4 1/3] Allow creation of arbitrary git-shell commands

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Err, actually it would probably be a good idea to
s/char *home = getenv("HOME");/const char *home = getenv("HOME");/

Greg



On Wed, Jul 28, 2010 at 5:31 PM, Greg Brockman <gdb@xxxxxxx> wrote:
> This provides a mechanism for the server to expose custom
> functionality to clients.  My particular use case is that I would like
> a way of discovering all repositories available for cloning.  A
> client that clones via
>
>  git clone user@xxxxxxxxxxx
>
> can invoke a command by
>
>  ssh user@xxxxxxxxxxx $command
>
> Signed-off-by: Greg Brockman <gdb@xxxxxxx>
> ---
>  shell.c |   44 ++++++++++++++++++++++++++++++++++++++++++--
>  1 files changed, 42 insertions(+), 2 deletions(-)
>
> As discussed on-list, it should be fine to trust the value of HOME.
> This patch differs from the previous only in the implementation of
> cd_to_homedir.
>
> diff --git a/shell.c b/shell.c
> index e4864e0..1e6077d 100644
> --- a/shell.c
> +++ b/shell.c
> @@ -3,6 +3,8 @@
>  #include "exec_cmd.h"
>  #include "strbuf.h"
>
> +#define COMMAND_DIR "git-shell-commands"
> +
>  static int do_generic_cmd(const char *me, char *arg)
>  {
>        const char *my_argv[4];
> @@ -33,6 +35,29 @@ static int do_cvs_cmd(const char *me, char *arg)
>        return execv_git_cmd(cvsserver_argv);
>  }
>
> +static int is_valid_cmd_name(const char *cmd)
> +{
> +       /* Test command contains no . or / characters */
> +       return cmd[strcspn(cmd, "./")] == '\0';
> +}
> +
> +static char *make_cmd(const char *prog)
> +{
> +       char *prefix = xmalloc((strlen(prog) + strlen(COMMAND_DIR) + 2));
> +       strcpy(prefix, COMMAND_DIR);
> +       strcat(prefix, "/");
> +       strcat(prefix, prog);
> +       return prefix;
> +}
> +
> +static void cd_to_homedir(void)
> +{
> +       char *home = getenv("HOME");
> +       if (!home)
> +               die("could not determine user's home directory; HOME is unset");
> +       if (chdir(home) == -1)
> +               die("could not chdir to user's home directory");
> +}
>
>  static struct commands {
>        const char *name;
> @@ -48,6 +73,7 @@ static struct commands {
>  int main(int argc, char **argv)
>  {
>        char *prog;
> +       const char **user_argv;
>        struct commands *cmd;
>        int devnull_fd;
>
> @@ -76,7 +102,7 @@ int main(int argc, char **argv)
>        else if (argc != 3 || strcmp(argv[1], "-c"))
>                die("What do you think I am? A shell?");
>
> -       prog = argv[2];
> +       prog = xstrdup(argv[2]);
>        if (!strncmp(prog, "git", 3) && isspace(prog[3]))
>                /* Accept "git foo" as if the caller said "git-foo". */
>                prog[3] = '-';
> @@ -99,5 +125,19 @@ int main(int argc, char **argv)
>                }
>                exit(cmd->exec(cmd->name, arg));
>        }
> -       die("unrecognized command '%s'", prog);
> +
> +       cd_to_homedir();
> +       if (split_cmdline(prog, &user_argv) != -1) {
> +               if (is_valid_cmd_name(user_argv[0])) {
> +                       prog = make_cmd(user_argv[0]);
> +                       user_argv[0] = prog;
> +                       execv(user_argv[0], (char *const *) user_argv);
> +               }
> +               free(prog);
> +               free(user_argv);
> +               die("unrecognized command '%s'", argv[2]);
> +       } else {
> +               free(prog);
> +               die("invalid command format '%s'", argv[2]);
> +       }
>  }
> --
> 1.7.0.4
>
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]