aclchecker.py 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. """
  4. (c) 2014-2018 - Copyright Red Hat Inc
  5. Authors:
  6. Patrick Uiterwijk <puiterwijk@redhat.com>
  7. """
  8. from __future__ import unicode_literals, print_function
  9. import subprocess
  10. import sys
  11. import os
  12. import requests
  13. if "SSH_ORIGINAL_COMMAND" not in os.environ:
  14. print("Welcome %s. This server does not offer ssh access." % sys.argv[1])
  15. sys.exit(0)
  16. # Since this is run by sshd, we don't have a way to set environment
  17. # variables ahead of time
  18. if "PAGURE_CONFIG" not in os.environ and os.path.exists(
  19. "/etc/pagure/pagure.cfg"
  20. ):
  21. os.environ["PAGURE_CONFIG"] = "/etc/pagure/pagure.cfg"
  22. # Here starts the code
  23. from pagure.config import config as pagure_config
  24. # Get the arguments
  25. if len(sys.argv) != 2:
  26. print("Invalid call, too few arguments", file=sys.stderr)
  27. sys.exit(1)
  28. remoteuser = sys.argv[1]
  29. args = os.environ["SSH_ORIGINAL_COMMAND"].split(" ")
  30. # Expects: <git-(receive|upload)-pack> <repopath>
  31. if len(args) != 2:
  32. print("Invalid call, too few inner arguments", file=sys.stderr)
  33. sys.exit(1)
  34. cmd = args[0]
  35. gitdir = args[1]
  36. if cmd not in ("git-receive-pack", "git-upload-pack"):
  37. print("Invalid call, invalid operation", file=sys.stderr)
  38. sys.exit(1)
  39. # Normalization of the gitdir
  40. # Git will encode the file path argument within single quotes
  41. if gitdir[0] != "'" or gitdir[-1] != "'":
  42. print("Invalid call: invalid path", file=sys.stderr)
  43. sys.exit(1)
  44. gitdir = gitdir[1:-1]
  45. # With the "ssh://hostname/repo.git", SSH sends "/repo.git"
  46. if gitdir[0] == "/":
  47. gitdir = gitdir[1:]
  48. # Always add .git for good measure
  49. if not gitdir.endswith(".git"):
  50. gitdir = gitdir + ".git"
  51. url = "%s/pv/ssh/checkaccess/" % pagure_config["APP_URL"]
  52. data = {"gitdir": gitdir, "username": remoteuser}
  53. resp = requests.post(url, data=data)
  54. if not resp.status_code == 200:
  55. print(
  56. "Error during lookup request: status: %s" % resp.status_code,
  57. file=sys.stderr,
  58. )
  59. sys.exit(1)
  60. result = resp.json()
  61. if not result["access"]:
  62. # The user does not have access to this repo, or project does
  63. # not exist. Whatever it is, no access.
  64. print("No such repository")
  65. sys.exit(1)
  66. # Now go run the configured command
  67. # We verified that cmd is either "git-receive-pack" or "git-send-pack"
  68. # and "path" is a path that points to a valid Pagure repository.
  69. if result["region"]:
  70. runner, env = pagure_config["SSH_COMMAND_REPOSPANNER"]
  71. else:
  72. runner, env = pagure_config["SSH_COMMAND_NON_REPOSPANNER"]
  73. result.update({"username": remoteuser, "cmd": cmd})
  74. for key in result:
  75. if result[key] is None:
  76. result[key] = ''
  77. runargs = [arg % result for arg in runner]
  78. if env:
  79. for key in env:
  80. os.environ[key] = env[key] % result
  81. os.execvp(runargs[0], runargs)