git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Junio C Hamano <junkio@cox.net>
To: git@vger.kernel.org
Cc: Linus Torvalds <torvalds@osdl.org>
Subject: [PATCH] Add git-shell.
Date: Sun, 23 Oct 2005 17:21:55 -0700	[thread overview]
Message-ID: <7vhdb7vk64.fsf_-_@assigned-by-dhcp.cox.net> (raw)
In-Reply-To: <Pine.LNX.4.64.0510231427230.10477@g5.osdl.org> (Linus Torvalds's message of "Sun, 23 Oct 2005 14:30:45 -0700 (PDT)")

This adds a very git specific restricted shell, that can be
added to /etc/shells and set to the pw_shell in the /etc/passwd
file, to give users ability to push into repositories over ssh
without giving them full interactive shell acount.

[jc: I updated Linus' patch to match what the current sq_quote()
 does.]

Signed-off-by: Junio C Hamano <junkio@cox.net>

---

   This one has the '!' dequoting I mentioned earlier, and
   actually has been tested twice.

   The system administrator should set things up so that the
   system default PATH environment variable lets users run the
   supported commands.

   We currently rely on the user to have a full shell access for
   repository administrative actions (e.g. git-init-db to create
   a repository, git-repack, and hooks management).  Probably
   some of them may need to become accessible from git-shell,
   but I do not know which ones offhand:

   - Creating a repository.  Probably wherever the user has
     write privilege, or maybe only under the home directory --
     the policy would be up to the system administrator, with
     usual filesystem quota applied.

   - I think setting up hooks should be forbidden -- the user
     can execute arbitrary commands if we allowed it.  Instead,
     the administrator can set things up for people, and would
     probably make creative use of hooks/update to implement
     access control (e.g. forbidding non-fast-forward pushes).

   - Similarly, packing can be left to hooks/post-update or cron
     job, either of which is under administrator control.

 Makefile |    2 +-
 quote.c  |   41 ++++++++++++++++++++++++++++++++++++++++-
 quote.h  |    6 ++++++
 shell.c  |   59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 106 insertions(+), 2 deletions(-)
 create mode 100644 shell.c

applies-to: c043f0993afe5c057409ef748ce313c89c20c7dc
f176536e2cd5949fa134d8b24dc07dd1f0744b6f
diff --git a/Makefile b/Makefile
index 5bdf3cc..5b0306d 100644
--- a/Makefile
+++ b/Makefile
@@ -116,7 +116,7 @@ PROGRAMS = \
 	git-merge-index$X git-mktag$X git-pack-objects$X git-patch-id$X \
 	git-peek-remote$X git-prune-packed$X git-read-tree$X \
 	git-receive-pack$X git-rev-list$X git-rev-parse$X \
-	git-send-pack$X git-show-branch$X \
+	git-send-pack$X git-show-branch$X git-shell$X \
 	git-show-index$X git-ssh-fetch$X \
 	git-ssh-upload$X git-tar-tree$X git-unpack-file$X \
 	git-unpack-objects$X git-update-index$X git-update-server-info$X \
diff --git a/quote.c b/quote.c
index 009e694..e662a7d 100644
--- a/quote.c
+++ b/quote.c
@@ -15,6 +15,11 @@
 #undef EMIT
 #define EMIT(x) ( (++len < n) && (*bp++ = (x)) )
 
+static inline int need_bs_quote(char c)
+{
+	return (c == '\'' || c == '!');
+}
+
 size_t sq_quote_buf(char *dst, size_t n, const char *src)
 {
 	char c;
@@ -23,7 +28,7 @@ size_t sq_quote_buf(char *dst, size_t n,
 
 	EMIT('\'');
 	while ((c = *src++)) {
-		if (c == '\'' || c == '!') {
+		if (need_bs_quote(c)) {
 			EMIT('\'');
 			EMIT('\\');
 			EMIT(c);
@@ -52,6 +57,40 @@ char *sq_quote(const char *src)
 	return buf;
 }
 
+char *sq_dequote(char *arg)
+{
+	char *dst = arg;
+	char *src = arg;
+	char c;
+
+	if (*src != '\'')
+		return NULL;
+	for (;;) {
+		c = *++src;
+		if (!c)
+			return NULL;
+		if (c != '\'') {
+			*dst++ = c;
+			continue;
+		}
+		/* We stepped out of sq */
+		switch (*++src) {
+		case '\0':
+			*dst = 0;
+			return arg;
+		case '\\':
+			c = *++src;
+			if (need_bs_quote(c) && *++src == '\'') {
+				*dst++ = c;
+				continue;
+			}
+		/* Fallthrough */
+		default:
+			return NULL;
+		}
+	}
+}
+
 /*
  * C-style name quoting.
  *
diff --git a/quote.h b/quote.h
index 2fdde3b..2486e6e 100644
--- a/quote.h
+++ b/quote.h
@@ -31,6 +31,12 @@
 extern char *sq_quote(const char *src);
 extern size_t sq_quote_buf(char *dst, size_t n, const char *src);
 
+/* This unwraps what sq_quote() produces in place, but returns
+ * NULL if the input does not look like what sq_quote would have
+ * produced.
+ */
+extern char *sq_dequote(char *);
+
 extern int quote_c_style(const char *name, char *outbuf, FILE *outfp,
 			 int nodq);
 extern char *unquote_c_style(const char *quoted, const char **endp);
diff --git a/shell.c b/shell.c
new file mode 100644
index 0000000..2c4789e
--- /dev/null
+++ b/shell.c
@@ -0,0 +1,59 @@
+#include "cache.h"
+#include "quote.h"
+
+static int do_generic_cmd(const char *me, char *arg)
+{
+	const char *my_argv[4];
+
+	arg = sq_dequote(arg);
+	if (!arg)
+		die("bad argument");
+
+	my_argv[0] = me;
+	my_argv[1] = arg;
+	my_argv[2] = NULL;
+
+	return execvp(me, (char**) my_argv);
+}
+
+static struct commands {
+	const char *name;
+	int (*exec)(const char *me, char *arg);
+} cmd_list[] = {
+	{ "git-receive-pack", do_generic_cmd },
+	{ "git-upload-pack", do_generic_cmd },
+	{ NULL },
+};
+
+int main(int argc, char **argv)
+{
+	char *prog;
+	struct commands *cmd;
+
+	/* We want to see "-c cmd args", and nothing else */
+	if (argc != 3 || strcmp(argv[1], "-c"))
+		die("What do you think I am? A shell?");
+
+	prog = argv[2];
+	argv += 2;
+	argc -= 2;
+	for (cmd = cmd_list ; cmd->name ; cmd++) {
+		int len = strlen(cmd->name);
+		char *arg;
+		if (strncmp(cmd->name, prog, len))
+			continue;
+		arg = NULL;
+		switch (prog[len]) {
+		case '\0':
+			arg = NULL;
+			break;
+		case ' ':
+			arg = prog + len + 1;
+			break;
+		default:
+			continue;
+		}
+		exit(cmd->exec(cmd->name, arg));
+	}
+	die("unrecognized command '%s'", prog);
+}
---
0.99.8.GIT

  parent reply	other threads:[~2005-10-24  0:22 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-10-22 22:22 Server side programs Andreas Ericsson
2005-10-23  0:30 ` Junio C Hamano
2005-10-23  9:41   ` User-relative paths (was: Server side programs) Andreas Ericsson
2005-10-23 18:37     ` Petr Baudis
2005-10-23 19:50       ` User-relative paths Junio C Hamano
2005-10-23 22:25         ` Petr Baudis
2005-10-23 22:30           ` Junio C Hamano
2005-10-24  6:28         ` Daniel Barkalow
2005-10-25  7:47       ` Andreas Ericsson
2005-10-23 19:56     ` Junio C Hamano
2005-10-23 21:30       ` Linus Torvalds
2005-10-23 22:57         ` Junio C Hamano
2005-10-23 23:02         ` Junio C Hamano
2005-10-24  1:08           ` H. Peter Anvin
2005-10-24  1:37             ` Linus Torvalds
2005-10-24  1:44               ` H. Peter Anvin
2005-10-24  1:56             ` Junio C Hamano
2005-10-24  0:21         ` Junio C Hamano [this message]
2005-10-24  0:52           ` [PATCH] Add git-shell Linus Torvalds
2005-10-24  0:55             ` Linus Torvalds
2005-10-24  1:36             ` Junio C Hamano
2005-10-24  2:08       ` User-relative paths Junio C Hamano
2005-10-25  9:11       ` [PATCH] git_progname (was: Re: User-relative paths) Andreas Ericsson
2005-10-25  9:31         ` Petr Baudis
2005-10-25 11:12           ` [PATCH] git_progname Andreas Ericsson
2005-10-25 12:53             ` Andreas Ericsson
2005-10-25 13:32               ` Petr Baudis
2005-10-26  6:07                 ` Junio C Hamano
2005-10-27  8:34           ` [PATCH] git_progname (was: Re: User-relative paths) Matthias Urlichs
2005-10-23  0:42 ` Server side programs Linus Torvalds

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=7vhdb7vk64.fsf_-_@assigned-by-dhcp.cox.net \
    --to=junkio@cox.net \
    --cc=git@vger.kernel.org \
    --cc=torvalds@osdl.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).