otac0n / WebGitNet

WebGit .NET is an ASP.NET MVC app that provides access to your git repositories over HTTP. It supports browsing in a web browser AND push / pull over Git's "Smart HTTP protocol".
zlib License
133 stars 62 forks source link

Launching git.exe as the authenticated user #78

Open codearoo opened 10 years ago

codearoo commented 10 years ago

Hi.. I'm lost.. I really want the git.exe to be run as the user logged in so that I can control what repos the user can read or write to based on Windows file security.

But I just can't seem to make it work.. I have the app pool using "application pool identity" but not sure that's right.. with the combination of Basic Auth + ASP.Net impersonation on.. you'd think that would do it.

If app pool is running under Local System, it allows all users to do everything, of course, because it's the system running things.

So .. ???

jberezanski commented 10 years ago

Unfortunately, due to the way ASP.NET impersonation works, the impersonated user identity will not flow to the git.exe process, at least not without extensive changes to the way WebGitNet invokes git.exe (http://support.microsoft.com/kb/889251). Even with those changes, the impersonated user account would need to be granted the "Replace a process level token" privilege, which would be dangerous from security perspective.

In my setup I use a combination of ASP.NET authorization rules and Git hooks for access control. ASP.NET authorization is easy to configure and can be used to allow/restrict all access at repository level (using location tags). Git hooks require more setup work, but can provide much more granular access control functionality, such as allowing only read access (blocking pushes), per-branch security or other custom authorization policies.

An example set of ASP.NET authorization rules could look like this:

<!-- each repo is accessible only by its project-specific group and admins -->
<!-- "browse" controls browsing via the web interface -->
<location path="browse/RepoA">
  <system.web>
    <allow roles=".\ProjectADevelopers" />
    <allow roles=".\GitAdministrators" />
    <deny users="*" />
  </system.web>
</location>
<!-- "git" controls git pushing/fetching -->
<location path="git/RepoA">
  <system.web>
    <allow roles=".\ProjectADevelopers" />
    <allow roles=".\GitAdministrators" />
    <deny users="*" />
  </system.web>
</location>
<location path="browse/RepoB">
  <system.web>
    <allow roles=".\ProjectBDevelopers" />
    <allow roles=".\GitAdministrators" />
    <deny users="*" />
  </system.web>
</location>
<location path="git/RepoB">
  <system.web>
    <allow roles=".\ProjectBDevelopers" />
    <allow roles=".\GitAdministrators" />
    <deny users="*" />
  </system.web>
</location>
<!-- restrict administrative tasks to designated admins only -->
<location path="create">
  <system.web>
    <allow roles=".\GitAdministrators" />
    <deny users="*" />
  </system.web>
</location>
<location path="manage">
  <system.web>
    <allow roles=".\GitAdministrators" />
    <deny users="*" />
  </system.web>
</location>
<!--  -->
<system.web>
  <allow roles=".\GitDevelopers" />
  <deny users="*" />
</system.web>

Using Git hooks for authorization requires a small modification to WebGitNet, because the identity of the user must be passed to the hook. The simplest way is via an environment variable, such as it is done here: https://github.com/maxim--s/WebGitNet/commit/4d7a5a85c3694e66c13e2cefed8176f0bbb05c3c (although in my fork I named the variable REMOTE_USER, for consistency with CGI). The hook (specifically, "pre-receive" and/or "update", see http://git-scm.com/book/en/Customizing-Git-Git-Hooks) needs to verify the user is authorized to push commits. The hooks can even be written in PowerShell (at least 3.0 is needed for correct stdin handling), which, thanks to the full power of .NET available, makes tasks such as checking Windows group membership a breeze.