From 999ad66ebccd9993792767f873528f4cee22b41c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C3=ADas=20Lang?= Date: Fri, 10 Apr 2020 23:58:48 -0300 Subject: [PATCH] Add git-daemon-export-ok to world readable repos This is an extra security measure, not a replacement to the /authorize method. In order to clone an HTTP(S) repo, the corresponding /authorize request must return 200, and the git-daemon-export-ok must exist inside the repository directory. The latter only will be required when the GIT_HTTP_EXPORT_ALL environment variable is unset. --- ...0bee7_create_git_daemon_export_ok_files.py | 36 +++++++++++++++++++ gitsrht/types/__init__.py | 23 +++++++++++- 2 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 gitsrht/alembic/versions/a8ad35a0bee7_create_git_daemon_export_ok_files.py diff --git a/gitsrht/alembic/versions/a8ad35a0bee7_create_git_daemon_export_ok_files.py b/gitsrht/alembic/versions/a8ad35a0bee7_create_git_daemon_export_ok_files.py new file mode 100644 index 0000000..176cd0f --- /dev/null +++ b/gitsrht/alembic/versions/a8ad35a0bee7_create_git_daemon_export_ok_files.py @@ -0,0 +1,36 @@ +"""Create git-daemon-export-ok files + +Revision ID: a8ad35a0bee7 +Revises: b4a2f2ed61b2 +Create Date: 2020-04-11 00:48:04.430870 + +""" + +# revision identifiers, used by Alembic. +revision = 'a8ad35a0bee7' +down_revision = 'b4a2f2ed61b2' + +from alembic import op +import sqlalchemy as sa +from sqlalchemy.orm import sessionmaker +from gitsrht.types import Repository +try: + from tqdm import tqdm +except ImportError: + def tqdm(iterable): + yield from iterable + + +Session = sessionmaker() + + +def upgrade(): + bind = op.get_bind() + session = Session(bind=bind) + print("Creating git-daemon-export-ok files") + for repo in tqdm(session.query(Repository).all()): + repo.update_visibility() + + +def downgrade(): + pass diff --git a/gitsrht/types/__init__.py b/gitsrht/types/__init__.py index 0ab477e..9a526cc 100644 --- a/gitsrht/types/__init__.py +++ b/gitsrht/types/__init__.py @@ -1,4 +1,6 @@ +import os import sqlalchemy as sa +from sqlalchemy import event from srht.database import Base from srht.oauth import ExternalUserMixin, ExternalOAuthTokenMixin from scmsrht.repos import BaseAccessMixin, BaseRedirectMixin @@ -17,7 +19,26 @@ class Redirect(Base, BaseRedirectMixin): pass class Repository(Base, BaseRepositoryMixin): - pass + def update_visibility(self): + if not os.path.exists(self.path): + # Repo dir not initialized yet + return + # In order to clone a public repo via http, a git-daemon-export-ok file + # must exist inside the repo directory. A private repo shouldn't have + # this file to improve security. + path = os.path.join(self.path, "git-daemon-export-ok") + should_exist = self.visibility in (RepoVisibility.public, RepoVisibility.unlisted) + if should_exist: + with open(path, 'w'): + pass + elif not should_exist and os.path.exists(path): + os.unlink(path) + +def update_visibility_event(mapper, connection, target): + target.update_visibility() + +event.listen(Repository, 'after_insert', update_visibility_event) +event.listen(Repository, 'after_update', update_visibility_event) from gitsrht.types.artifact import Artifact from gitsrht.types.sshkey import SSHKey -- 2.38.4