[scponly] [PATCH] Add git compatibility mode

Benjamin Cama benjamin.cama at telecom-bretagne.eu
Wed Jan 16 12:05:46 EST 2013


Hi,

Some times ago, I needed my scponly account to also be able to host git
repositories. This is usefull to me as I found both the “direct” scp,
and the repository methods to be usefull for sharing my work, but didn't
want separate accounts for these two close things.

So I wrote this patch, that adds the ability to run git-shell, which
gives push/pull access to a git repository.  Please note that it doesn't
thoroughly check the arguments, as git-shell should already take care of
those.

And also, I didn't add much documentation, as I didn't know exactly how
to word it, as it's quite straightforward to me.

Any comments are welcome.

Regards,
Benjamin

Signed-off-by: Benjamin Cama <benjamin.cama at telecom-bretagne.eu>
---
 config.h.in  |    9 +++++++++
 configure.in |   15 +++++++++++++++
 scponly.c    |   55 +++++++++++++++++++++++++++++++++++++++++++++++++++----
 3 files changed, 75 insertions(+), 4 deletions(-)

diff --git a/config.h.in b/config.h.in
index 9b2d950..d56f719 100644
--- a/config.h.in
+++ b/config.h.in
@@ -15,6 +15,7 @@
 #undef ENABLE_SCP2
 #undef ENABLE_SFTP
 #undef SVNSERV_COMPAT
+#undef GIT_COMPAT
 #undef ENABLE_WILDCARDS
 #undef RESTRICTIVE_FILENAMES
 #undef CHROOTED_NAME
@@ -99,3 +100,11 @@
 #undef PROG_QUOTA
 #endif
 
+/* git compatibility */
+#ifdef GIT_COMPAT
+#undef PROG_GIT_SHELL
+#ifndef USE_SAFE_ENVIRONMENT
+#define USE_SAFE_ENVIRONMENT
+#endif
+#endif
+
diff --git a/configure.in b/configure.in
index 4b90fbc..5eb9471 100644
--- a/configure.in
+++ b/configure.in
@@ -229,6 +229,16 @@ AC_ARG_ENABLE([quota-compat],
               echo -n      dnl  Defaults to off, must be turned on explicitly
       ])
 
+AC_ARG_ENABLE([git-compat],
+      AC_HELP_STRING([--enable-git-compat], [enable git compatibility]),
+      [
+              if test "x$enableval" != "xno"; then
+                      AC_DEFINE([GIT_COMPAT])
+              fi
+      ],[
+              echo -n      dnl  Defaults to off, must be turned on explicitly
+      ])
+
 if test "x$scponly_scp_compat" != "x"; then
 	AC_MSG_NOTICE([enabling core WinSCP and Vanilla SCP binaries...])
 	  if test "x$scponly_explicit_sftpserver_path" = "x"; then
@@ -305,6 +315,11 @@ if test "x$enable_quota_compat" != "x" && test "x$enable_quota_compat" != "xno";
 	SCPONLY_PATH_PROG_DEFINE([PROG_QUOTA],   [quota],   [/bin:/usr/bin:/sbin:/usr/sbin])
 fi
 
+if test "x$enable_git_compat" != "x" && test "x$enable_git_compat" != "xno"; then
+	AC_MSG_NOTICE([enabling git compatability...])
+	SCPONLY_PATH_PROG_DEFINE([PROG_GIT_SHELL],   [git-shell],   [/bin:/usr/bin:/usr/local/bin])
+fi
+
 dnl with-sftp-server conditionals:
 if test "x$scponly_sftp_compat" != "x"; then
   AC_MSG_NOTICE([enabling SFTP compatability...])
diff --git a/scponly.c b/scponly.c
index f33851b..a0f8295 100644
--- a/scponly.c
+++ b/scponly.c
@@ -200,9 +200,13 @@ char * allowed_env_vars[] =
 	"SFTP_LOG_LEVEL",
 	"SFTP_LOG_FACILITY",
 #endif
-#ifdef UNISON_COMPAT
+#if defined(UNISON_COMPAT) || defined(GIT_COMPAT)
 	"HOME",
 #endif
+#ifdef GIT_COMPAT
+	"SSH_CLIENT",
+	"SSH_CONNECTION",
+#endif
 	NULL
 };
 
@@ -211,6 +215,7 @@ int process_pre_chroot_request(char **av);
 int winscp_regular_request(char *request);
 int winscp_transit_request(char *request);
 int process_winscp_requests(void);
+int process_git_request(char *request);
 
 int main (int argc, char **argv) 
 {
@@ -427,10 +432,21 @@ int main (int argc, char **argv)
 			exit(EXIT_FAILURE);
 		}
 	}
-#else
-	if (0)	{}	/*  placeholder */
+	else
+#endif
+#ifdef GIT_COMPAT
+	if (argc==3 && !strncmp(argv[2], "git-", 4))
+	{
+		debug(LOG_DEBUG, "entering git compatibility mode [%s]",logstamp());
+		if (-1==process_git_request(argv[2]))
+		{
+			syslog(LOG_ERR, "failed git compatibility mode [%s]", logstamp());
+			exit(EXIT_FAILURE);
+		}
+	}
+	else
 #endif
-	else if (-1==process_ssh_request(argv[2]))
+	if (-1==process_ssh_request(argv[2]))
 	{
 		syslog(LOG_ERR, "bad request: %s [%s]", argv[2], logstamp());
 		exit(EXIT_FAILURE);
@@ -874,4 +890,35 @@ int process_ssh_request(char *request)
 		exit(EXIT_FAILURE);
 }
 
+#ifdef GIT_COMPAT
+int process_git_request(char *request)
+{
+	char *av[4];
+	char **tenv, **env = NULL;
+	int retval;
+
+	debug(LOG_DEBUG, "processing git request: \"%s\"\n", request);
+	av[0] = strdup(PROG_GIT_SHELL);
+	av[1] = strdup("-c");
+	av[2] = strdup(request);
+	av[3] = NULL;
+#ifdef USE_SAFE_ENVIRONMENT
+	safeenv[0] = NULL;
+	filter_allowed_env_vars();
+	tenv = safeenv;
+	if (debuglevel) {
+		while (NULL != *tenv) {
+			syslog(LOG_DEBUG, "Environment contains \"%s\"", *tenv++);
+		}
+	}
+	env = safeenv;
+#endif
+	debug(LOG_DEBUG, "about to exec \"%s\" (%s)", av[0], logstamp());
+	retval=execve(av[0],av,env);
+	syslog(LOG_ERR, "failed: %s -c %s with error %s(%u) (%s)", PROG_GIT_SHELL, request, strerror(errno), errno, logstamp());
+	discard_child_vectors(av);
+	return retval;
+}
+#endif
+
 /* vim: set noet sw=4 ts=4: */
-- 
1.7.2.5




More information about the scponly mailing list