summaryrefslogtreecommitdiffstats
path: root/mansrht-shell
diff options
context:
space:
mode:
Diffstat (limited to 'mansrht-shell')
-rwxr-xr-xmansrht-shell76
1 files changed, 76 insertions, 0 deletions
diff --git a/mansrht-shell b/mansrht-shell
new file mode 100755
index 0000000..ec264cf
--- /dev/null
+++ b/mansrht-shell
@@ -0,0 +1,76 @@
+#!/usr/bin/env python3
+import sys
+import os
+try:
+ f = open("/var/log/man-srht-shell", "a")
+ os.close(sys.stderr.fileno())
+ os.dup2(f.fileno(), sys.stderr.fileno())
+except Exception as ex:
+ sys.stderr.write("Unable to open log for writing\n")
+ sys.stderr.write(str(ex) + "\n")
+import requests
+import shlex
+from datetime import datetime
+from srht.config import cfg
+from srht.validation import Validation
+from srht.database import DbSession
+db = DbSession(cfg("man.sr.ht", "connection-string"))
+from mansrht.access import has_access, UserAccess
+from mansrht.types import User, Wiki
+db.init()
+
+def log(s, *args):
+ sys.stderr.write("{} {}\n".format(datetime.now().isoformat(),
+ s.format(*args) if isinstance(s, str) else str(s)))
+ sys.stderr.flush()
+
+root = cfg("man.sr.ht", "origin")
+repos = cfg("man.sr.ht", "repo-path")
+
+_cmd = os.environ.get("SSH_ORIGINAL_COMMAND")
+if not _cmd:
+ _cmd = ""
+if len(sys.argv) < 2:
+ log("Error: expected 2 arguments from SSH")
+ sys.exit(1)
+user_id = sys.argv[1]
+ssh_key = sys.argv[2]
+
+user = User.query.filter(User.id == user_id).first()
+if not user:
+ log("Unknown user ID {}", user_id)
+ sys.exit(1)
+log("User: {}", user.username)
+
+cmd = shlex.split(_cmd)
+valid_commands = ["git-receive-pack", "git-upload-pack", "git-upload-archive"]
+if len(cmd) < 1 or not cmd[0] in valid_commands:
+ log("Not permitting unacceptable command")
+ print("Hi {}! You've successfully authenticated, ".format(user.username) +
+ "but I do not provide an interactive shell. Bye!")
+ sys.exit(128)
+os.chdir(repos)
+path = os.path.abspath(cmd[-1])
+if not path.startswith(repos):
+ log("Access denied")
+ sys.exit(128)
+cmd[-1] = path
+
+if path == os.path.join(repos, "root"):
+ if cmd[0] == "git-receive-pack" and not user.admin:
+ sys.exit(128)
+else:
+ wiki = Wiki.query.filter(Wiki.path == path).first()
+ if not wiki:
+ sys.exit(128)
+
+ if cmd[0] == "git-receive-pack":
+ if not has_access(wiki, UserAccess.write, user):
+ sys.exit(128)
+ else:
+ if not has_access(wiki, UserAccess.read, user):
+ sys.exit(128)
+
+log("Executing {}", " ".join(cmd))
+sys.stderr.close()
+os.execvp(cmd[0], cmd)