def serve(cname, enable_repo_config=False, enable_repo_group=False,
          enable_user_repos=False,
          enable_mozreview_ldap_associate=False):
    ssh_command = os.getenv('SSH_ORIGINAL_COMMAND')
    if not ssh_command:
        sys.stderr.write(SUCCESSFUL_AUTH % os.environ['USER'])
        sys.stderr.write(NO_SSH_COMMAND)
        sys.exit(1)
    elif ssh_command.startswith('hg'):
        repo_expr = re.compile('(.*)\s+-R\s+([^\s]+\s+)(.*)')
        if repo_expr.search(ssh_command):
            [(hg_path, repo_path, hg_command)] = repo_expr.findall(ssh_command)
            if hg_command == 'serve --stdio' and check_repo_name(repo_path):
                hg_arg_string = HG + ' -R ' + DOC_ROOT + '/' + repo_path + hg_command
                hg_args = hg_arg_string.split()
                os.execv(HG, hg_args)
            else:
                sys.stderr.write("Thank you dchen! but.. I don't think so!\n")
                sys.exit(1)
    elif ssh_command.startswith('clone '):
        if not enable_user_repos:
            print('user repository management is not enabled')
            sys.exit(1)

        args = ssh_command.replace('clone', '').split()
        if check_repo_name(args[0]):
            if len(args) == 1:
                make_repo_clone(cname, args[0], None)
            elif len(args) == 2:
                make_repo_clone(cname, args[0], args[1])
            sys.exit(0)
        sys.stderr.write('clone usage: ssh hg.mozilla.org clone newrepo '
                         '[srcrepo]\n')
        sys.exit(1)
    elif ssh_command.startswith('edit '):
        if not enable_user_repos:
            print('user repository management is not enabled')
            sys.exit(1)

        args = ssh_command.replace('edit', '',  1).split()
        if check_repo_name(args[0]):
            if len(args) == 1:
                edit_repo(cname, args[0], False)
            elif len(args) == 3 and args[1] == 'delete' and args[2] == 'YES':
                edit_repo(cname, args[0], True)
            else:
                sys.stderr.write('edit usage: ssh hg.mozilla.org edit '
                                 '[userrepo delete] - WARNING: will not '
                                 'prompt!\n')
                sys.exit(1)
    elif ssh_command.startswith('repo-group'):
        if not enable_repo_group:
            print('repo-group command not available')
            sys.exit(1)

        args = ssh_command.replace('repo-group', '').split()
        if check_repo_name(args[0]):
            print(repo_group.repo_owner(args[0]))
    elif ssh_command.startswith('repo-config '):
        if not enable_repo_config:
            print('repo-config command not available')
            sys.exit(1)

        args = ssh_command.split()[1:]
        repo = args[0]
        if check_repo_name(repo):
            hgrc = '/repo/hg/mozilla/%s/.hg/hgrc' % repo
            if os.path.exists(hgrc):
                with open(hgrc, 'rb') as fh:
                    sys.stdout.write(fh.read())
    elif ssh_command.startswith('mozreview-ldap-associate'):
        if not enable_mozreview_ldap_associate:
            print('mozreview-ldap-associate command not available')
            sys.exit(1)

        args = ssh_command.split()[1:]
        sys.exit(mozreview_ldap_associate(args))
    else:
        sys.stderr.write(SUCCESSFUL_AUTH % os.environ['USER'])
        sys.stderr.write(INVALID_SSH_COMMAND)
        sys.exit(1)
Exemple #2
0
def serve(cname, enable_repo_config=False, enable_repo_group=False,
          enable_user_repos=False,
          enable_mozreview_ldap_associate=False):
    ssh_command = os.getenv('SSH_ORIGINAL_COMMAND')
    if not ssh_command:
        sys.stderr.write(SUCCESSFUL_AUTH % os.environ['USER'])
        sys.stderr.write(group_membership_message(os.environ['USER']))
        sys.stderr.write('\n')
        sys.stderr.write(NO_SSH_COMMAND)
        sys.exit(1)

    args = shlex.split(ssh_command)

    if args[0] == 'hg':
        # SECURITY it is critical that invoked commands be limited to
        # `hg -R <path> serve --stdio`. If a user manages to pass arguments
        # to coerce Mercurial into say opening a debugger, that is effectively
        # giving them a remote shell. We require that command arguments match
        # an exact pattern and that the repo name is sanitized.
        if args[1] != '-R' or args[3:] != ['serve', '--stdio']:
            sys.stderr.write('invalid `hg` command executed; can only run '
                             'serve --stdio\n')
            sys.exit(1)

        # At this point, the only argument not validated to match exact bytes
        # is the value for -R. We sanitize that through our repo name validator
        # *and* verify it exists on disk.

        repo_path = args[2]
        # This will ensure the repo path is essentially alphanumeric. So we
        # don't have to worry about ``..``, Unicode, spaces, etc.
        assert_valid_repo_name(repo_path)
        full_repo_path = '%s/%s' % (DOC_ROOT, repo_path)

        if not os.path.isdir('%s/.hg' % full_repo_path):
            sys.stderr.write('requested repo %s does not exist\n' % repo_path)
            sys.exit(1)

        os.execv(HG, [HG, '-R', full_repo_path, 'serve', '--stdio'])

    elif args[0] == 'clone':
        if not enable_user_repos:
            print('user repository management is not enabled')
            sys.exit(1)

        if len(args) == 1:
            sys.stderr.write('clone usage: ssh hg.mozilla.org clone newrepo '
                             '[srcrepo]\n')
            sys.exit(1)
        assert_valid_repo_name(args[1])
        if len(args) == 2:
            make_repo_clone(cname, args[1], None)
        elif len(args) == 3:
            make_repo_clone(cname, args[1], args[2])
        sys.exit(0)
    elif args[0] == 'edit':
        if not enable_user_repos:
            print('user repository management is not enabled')
            sys.exit(1)

        if len(args) == 2:
            assert_valid_repo_name(args[1])
            edit_repo(cname, args[1], False)
        elif len(args) == 4 and args[2] == 'delete' and args[3] == 'YES':
            assert_valid_repo_name(args[1])
            edit_repo(cname, args[1], True)
        else:
            sys.stderr.write('edit usage: ssh hg.mozilla.org edit '
                             '[userrepo delete] - WARNING: will not '
                             'prompt!\n')
            sys.exit(1)
    elif args[0] == 'repo-group':
        if not enable_repo_group:
            print('repo-group command not available')
            sys.exit(1)

        assert_valid_repo_name(args[1])
        print(repo_group.repo_owner(args[1]))
    elif args[0] == 'repo-config':
        if not enable_repo_config:
            print('repo-config command not available')
            sys.exit(1)

        repo = args[1]
        assert_valid_repo_name(repo)
        hgrc = '/repo/hg/mozilla/%s/.hg/hgrc' % repo
        if os.path.exists(hgrc):
            with open(hgrc, 'rb') as fh:
                sys.stdout.write(fh.read())
    else:
        sys.stderr.write(SUCCESSFUL_AUTH % os.environ['USER'])
        sys.stderr.write(INVALID_SSH_COMMAND)
        sys.exit(1)
Exemple #3
0
def serve(cname,
          enable_repo_config=False,
          enable_repo_group=False,
          enable_user_repos=False,
          enable_mozreview_ldap_associate=False):
    ssh_command = os.getenv('SSH_ORIGINAL_COMMAND')
    if not ssh_command:
        sys.stderr.write(SUCCESSFUL_AUTH % os.environ['USER'])
        sys.stderr.write(NO_SSH_COMMAND)
        sys.exit(1)
    elif ssh_command.startswith('hg'):
        repo_expr = re.compile('(.*)\s+-R\s+([^\s]+\s+)(.*)')
        if repo_expr.search(ssh_command):
            [(hg_path, repo_path, hg_command)] = repo_expr.findall(ssh_command)
            if hg_command == 'serve --stdio' and check_repo_name(repo_path):
                hg_arg_string = HG + ' -R ' + DOC_ROOT + '/' + repo_path + hg_command
                hg_args = hg_arg_string.split()
                os.execv(HG, hg_args)
            else:
                sys.stderr.write("Thank you dchen! but.. I don't think so!\n")
                sys.exit(1)
    elif ssh_command.startswith('clone '):
        if not enable_user_repos:
            print('user repository management is not enabled')
            sys.exit(1)

        args = ssh_command.replace('clone', '').split()
        if check_repo_name(args[0]):
            if len(args) == 1:
                make_repo_clone(cname, args[0], None)
            elif len(args) == 2:
                make_repo_clone(cname, args[0], args[1])
            sys.exit(0)
        sys.stderr.write('clone usage: ssh hg.mozilla.org clone newrepo '
                         '[srcrepo]\n')
        sys.exit(1)
    elif ssh_command.startswith('edit '):
        if not enable_user_repos:
            print('user repository management is not enabled')
            sys.exit(1)

        args = ssh_command.replace('edit', '', 1).split()
        if check_repo_name(args[0]):
            if len(args) == 1:
                edit_repo(cname, args[0], False)
            elif len(args) == 3 and args[1] == 'delete' and args[2] == 'YES':
                edit_repo(cname, args[0], True)
            else:
                sys.stderr.write('edit usage: ssh hg.mozilla.org edit '
                                 '[userrepo delete] - WARNING: will not '
                                 'prompt!\n')
                sys.exit(1)
    elif ssh_command.startswith('repo-group'):
        if not enable_repo_group:
            print('repo-group command not available')
            sys.exit(1)

        args = ssh_command.replace('repo-group', '').split()
        if check_repo_name(args[0]):
            print(repo_group.repo_owner(args[0]))
    elif ssh_command.startswith('repo-config '):
        if not enable_repo_config:
            print('repo-config command not available')
            sys.exit(1)

        args = ssh_command.split()[1:]
        repo = args[0]
        if check_repo_name(repo):
            hgrc = '/repo/hg/mozilla/%s/.hg/hgrc' % repo
            if os.path.exists(hgrc):
                with open(hgrc, 'rb') as fh:
                    sys.stdout.write(fh.read())
    elif ssh_command.startswith('mozreview-ldap-associate'):
        if not enable_mozreview_ldap_associate:
            print('mozreview-ldap-associate command not available')
            sys.exit(1)

        args = ssh_command.split()[1:]
        sys.exit(mozreview_ldap_associate(args))
    else:
        sys.stderr.write(SUCCESSFUL_AUTH % os.environ['USER'])
        sys.stderr.write(INVALID_SSH_COMMAND)
        sys.exit(1)