[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