A note on Unix users

Normally the http daemon is configured to run as its own user, and gitano is configured to run as its own user for privilege separation.

CGI programs run by the HTTP daemon need to be run as the gitano user to be able to operate correctly.

So to make this work you need to:

  1. Run the HTTP daemon as the git user, which is unsafe when the HTTP daemon is used for non-git purposes.

    $ sudo sed -i -e '/server.username/c server.username = "git"' \
        -e '/server.groupname/c server.groupname = "git"' \
        -e '/server.errorlog/c server.errorlog = "/home/gitano/http-error.log"' \
        /etc/lighttpd/lighttpd.conf
    
  2. Add the git user as an alias to the http daemon's user instead of how the user is normally created:

    $ useradd --non-unique --uid $(id -u www-data) --gid $(id -g www-data)
    
  3. Run the git protocols in a different server reverse-proxied to a different front-end web server. For instructions on how to configure that see relevant documentation

Enabling passwords

Using the HTTP interface requires password authentication.

This is not enabled by default, it requires cloning the gitano-admin repository, modifying site.conf and changing use_htpasswd's value to "yes".

$ git clone "ext::ssh -i ~/.ssh/gitano-admin.pub git@localhost %S gitano-admin.git" gitano-admin
$ cd gitano-admin
$ sed -i '/^use_htpasswd/d' site.conf
$ printf 'use_htpasswd "yes"\n" >>site.conf
$ git add site.conf
$ git commit -m 'Enable htpasswd'
$ git push origin HEAD
Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 371 bytes | 0 bytes/s, done.
Total 3 (delta 1), reused 0 (delta 0)
remote: [gitano] Verifying new gitano-admin master
remote: [gitano] Looks okay
remote: [gitano] Scanning repositories to apply hook/rules updates...
remote: [gitano] <gitano-admin> Any changes to hooks etc have been applied
remote: [gitano] All repositories updated where possible.
remote: [gitano] SSH authorised key file updated
To ext::ssh -i ~/.ssh/gitano-admin.pub git@localhost %S gitano-admin.git
   4fa3d30..0e303d1  HEAD -> master

Then a user's password may be set with the passwd gitano command.

$ ssh -i ~/.ssh/gitano-admin.pub git@localhost passwd

Smart HTTP support

Ensure mod_setenv is added to the set of loaded modules in /etc/lighttpd/lighttpd.conf.

If apache2-utils is not installed then some other provider of the htpasswd program must be in the default binary search path.

Assuming a default installation, write the following configuration to /etc/lighttpd/conf-available/02-gitano-smart-http.conf.

$HTTP["url"] =~ "^/git/.*$" {
    alias.url += ( "/git" => "/usr/lib/gitano/bin/gitano-smart-http.cgi" )

    cgi.assign = ("" => "")
    setenv.add-environment = (
        "GIT_HTTP_EXPORT_ALL" => "",
        "GIT_PROJECT_ROOT" => "/home/git/repos",
        "HOME" => "/home/git",
        "GITANO_ROOT" => "/home/git/repos",
    )

    auth.require = (
        "/" => (
            "method" => "basic",
            "realm" => "Git Access",
            "require" => "valid-user"
        )
    )

    auth.backend = "htpasswd"
    auth.backend.htpasswd.userfile = "/home/git/htpasswd"
}

Enable it and its dependent config with:

$ cd /etc/lighttpd/conf-enabled
$ for conf in 05-auth.conf 10-cgi.conf 20-gitano-smart-http.conf; do sudo ln -sf ../conf-available/"$conf"; done

It should now be possible to clone repositories by prefixing the repository path with git/.

$ git clone http://admin@localhost/git/gitano-admin.git hga
Cloning into 'hga'...
Password for 'http://admin@localhost': 
remote: Counting objects: 42, done.
remote: Compressing objects: 100% (41/41), done.
remote: Total 42 (delta 5), reused 0 (delta 0)
Unpacking objects: 100% (42/42), done.
Checking connectivity... done.

HTTP Command support

Ensure mod_setenv is added to the set of loaded modules in /etc/lighttpd/lighttpd.conf.

Gitano commands can also be accessed over HTTP.

$HTTP["url"] =~ ".*/gitano-command.cgi$" {
    alias.url += ( "/gitano-command.cgi" => "/usr/lib/gitano/bin/gitano-command.cgi" )

    cgi.assign = ("" => "")
    setenv.add-environment = (
            "HOME" => "/home/git",
            "GITANO_ROOT" => "/home/git/repos/"
    )

    auth.require = (
        "/" => (
            "method" => "basic",
            "realm" => "Git Access",
            "require" => "valid-user"
        )
    )

    auth.backend = "htpasswd"
    auth.backend.htpasswd.userfile = "/home/git/htpasswd"
}

Enable this config and its dependencies with:

$ cd /etc/lighttpd/conf-enabled
$ for conf in 05-auth.conf 10-cgi.conf 20-gitano-command.conf; do sudo ln -sf ../conf-available/"$conf"; done

Now commands can be run with curl by requesting the gitano-command.cgi page with the command set in the cmd parameter of the query string.

$ curl --user admin http://localhost/gitano-command.cgi?cmd=whoami
Enter host password for user 'admin':
    User name: admin
    Real name: Administrator
Email address: admin@administrator.local
      SSH key: default => user@example
    In groups: gitano-admin: Gitano Instance Administrators

The password can be changed with the passwd command and the --data option to provide the new password

$ curl --user admin http://localhost/gitano-command.cgi?cmd=passwd --data newpass
Enter host password for user 'admin':
[gitano] SSH authorised key file updated
[gitano] Updated password for admin

CGit configuration

Write the following configuration to /etc/lighttpd/conf-available/02-cgit.conf.

$HTTP["url"] =~ "^/cgit" {
    $HTTP["url"] =~ "^/cgit-css" {
        server.document-root = "/usr/share/cgit"
        alias.url += (
            "/cgit-css" => "/usr/share/cgit",
        )
    }

    $HTTP["url"] !~ "^/cgit-css" {
        alias.url += (
            "/cgit" => "/usr/lib/cgit/cgit.cgi",
        )

        cgi.assign = ("" => "")
    }
}

Enable the new configuration.

$ for conf in 05-auth.conf 10-cgi.conf 20-cgit.conf; do sudo ln -sf ../conf-available/"$conf"; done

Add the following to /etc/cgitrc:

strict-export=git-daemon-export-ok
scan-path=/home/git/repos/

Now you should be able to see the cgit interface at http://localhost/cgit.

It will be empty because gitano will only authorise cgit to display repositories that are publicly readable.

See Anonymous Read access setup for how to enable this.

If CGit still shows no repositories, but that's because this rule will show everything but gitano-admin. This can be tested further by adding more repositories:

$ ssh -i ~/.ssh/gitano-admin.pub git@localhost create testrepo

If your version of CGit is sufficiently new, this repository can be hidden from the listing, but still viewable at http://localhost/cgit/testrepo.git/ by running:

$ ssh -i ~/.ssh/gitano-admin.pub git@localhost config testrepo set project.archived true