--- /dev/null
+# path to git projects (<project>.git)
+$projectroot = "/data/vcs/git";
+
+# directory to use for temp files
+$git_temp = "/tmp";
+
+# target of the home link on top of all pages
+#$home_link = $my_uri || "/";
+
+# html text to include at home page
+$home_text = "indextext.html";
+
+# file with project list; by default, simply scan the projectroot dir.
+$projects_list = $projectroot;
+
+# stylesheet to use
+$stylesheet = "/gitweb.css";
+
+# logo to use
+$logo = "/git-logo.png";
+
+# the 'favicon'
+$favicon = "/git-favicon.png";
+
+@git_base_url_list = (
+ "http://git.stderr.nl/git",
+ "ssh://git.stderr.nl/data/vcs/git"
+)
--- /dev/null
+[collections]
+/ = /data/vcs/hg
--- /dev/null
+#!/usr/bin/python
+import os
+import re
+import pwd
+import grp
+import shutil
+import stat
+
+ROOT_DIR="/data/www"
+
+# SITES = [(sitename, application_list)]
+# application_list = [application_name, (application_name, command, ...)]
+# Here, sitename is the name of the site. This folder name should exist below ROOT_DIR and
+# is also used below SOCKET_DIR. The site name is also translated to a user and
+# group name by replacing dots by dashes and prepending USER_PREFIX and
+# GROUP_PREFIX.
+#
+# application_list specifies the applications to start for this site. These can
+# be generic (when only application_name is given), in which case the command
+# is looked up in APPLICATIONS using the application_name. For a site-specific
+# application, command is the command that should be run. It will be prefixed
+# with the site's root dir, if is not an absolute path.
+
+
+SITES=[
+# ('stderr.nl', ['php']),
+# ('stdin.nl', ['php']),
+ ('stdout.nl', ['php']),
+# ('evolution-events.nl', ['php']), #, ('xerxes', 'applications/xerxes/manage.py runfcgi'), ('wipi', 'applications/wipi/wipi.fcgi')]),
+# ('stdio.flexvps.nl', ['php']),
+# ('foresightsecurity.nl', ['php']),
+]
+
+# Generic applications that can be run for any site
+# Maps application_name to application_command. application_command will be
+# prefixed with the site's root dir, if it is not an absolute path.
+APPLICATIONS={"php": "/usr/bin/php-cgi"}
+
+# Kill these procs before starting new ones. Only processes of these names that
+# are run by the sites in SITES are killed. This is a bit hackish, we should
+# really be using pidfiles...
+KILL_PROCS=['php-cgi', 'manage.py']
+
+## ABSOLUTE path to the spawn-fcgi binary
+SPAWNFCGI="/usr/bin/spawn-fcgi"
+
+## Dir in which to create the UNIX sockets to listen on
+SOCKET_DIR="%s/var/fcgi" % (ROOT_DIR)
+
+## number of PHP children to spawn
+PHP_FCGI_CHILDREN=2
+
+## maximum number of requests a single PHP process can serve before it is restarted
+PHP_FCGI_MAX_REQUESTS=1000
+
+# The user to run as, will be prefixed to the sitename
+USER_PREFIX="httpd-"
+# The group to run as.
+SCRIPT_GROUP="httpd-users"
+# The group that should be able to use the sockets created
+HTTPD_GROUP="www-data"
+
+# Will be postfixed to the site's root and exported in the PHPRC variable.
+PHPRC_DIR="conf"
+
+#### END OF CONFIG ####
+
+for (site, apps) in SITES:
+ site_name = re.sub('\.', '-', site)
+
+ ## switch to the following user / group
+ user_id = "%s%s" % (USER_PREFIX, site_name)
+
+ # Find the site dir
+ site_dir = os.path.join(ROOT_DIR, site)
+ socket_dir = os.path.join(SOCKET_DIR, site_name)
+
+ if not site_dir:
+ raise Exception("Site dir does not exist: %s" % (site_dir))
+
+
+ # Kill existing processes first
+ for procname in KILL_PROCS:
+ os.system('killall --user %s %s' % (user_id, procname))
+
+ # Remove old sockets
+ if os.path.exists(socket_dir):
+ shutil.rmtree(socket_dir)
+
+ # Create dir for sockets. Make owning group root and set group write
+ # permissions, so the mask field in the acl will not block out anything.
+ os.makedirs(socket_dir)
+ os.chown(socket_dir, pwd.getpwnam(user_id)[2], grp.getgrnam(HTTPD_GROUP)[2])
+ #os.chmod(socket_dir, stat.S_IRWXU)
+
+ for app in apps:
+ # Unpack app tuple or lookup app command in APPLICATIONS
+ if isinstance(app, tuple):
+ if len(app) == 2:
+ (app_name, app_command) = app
+ else:
+ raise Exception("Wrong number of elements in site tuple: %s", app)
+ else:
+ app_name = app
+ app_command = APPLICATIONS[app_name]
+
+ # Prefix with site dir if not an absolute path
+ if not os.path.isabs(app_command):
+ app_command = os.path.join(site_dir, app_command)
+
+ # Create socket filename
+ socket = os.path.join(socket_dir, app_name)
+
+ # Build the command
+ # TODO: Wrap this in env to clear up the environment
+ spawnfcgi = '%s -s "%s" -u "%s" -g "%s"' % (SPAWNFCGI, socket, user_id, SCRIPT_GROUP)
+ fcgiapp = ' -- %s' % (app_command)
+
+ if app_name == 'php':
+ os.environ['PHP_FCGI_MAX_REQUESTS'] = str(PHP_FCGI_MAX_REQUESTS)
+ phprc = os.path.join(site_dir, PHPRC_DIR, 'php.ini')
+ if os.path.exists(phprc):
+ #os.environ['PHPRC'] = phprc
+ fcgiapp += ' -c %s' % (phprc)
+ spawnfcgi += ' -C %s' % (PHP_FCGI_CHILDREN)
+
+
+ print spawnfcgi + fcgiapp
+ os.system(spawnfcgi + fcgiapp)
+
+ # Ensure www-data can write to the socket :-S
+ # Spawn-fcgi explicitely chmods the socket after creation, very
+ # annoying
+ os.chmod(socket, stat.S_IRWXU | stat.S_IRWXG)
--- /dev/null
+# Debian lighttpd configuration file
+#
+
+# Chroot into our root-dir
+#server.chroot = "/data/www"
+
+#var.root-dir = ""
+var.root-dir = "/data/www"
+var.conf-dir = "/etc/lighttpd"
+var.fcgi-dir = var.root-dir + "/var/fcgi"
+
+## modules to load
+server.modules = (
+ "mod_access",
+ "mod_alias",
+ "mod_accesslog",
+ "mod_rewrite",
+ "mod_redirect",
+ "mod_evhost",
+ "mod_cgi",
+ "mod_fastcgi",
+ "mod_auth",
+)
+
+# Set a default catch-all document root, which should never be used.
+server.document-root = var.root-dir + "/default/htdocs"
+
+## where to upload files to, purged daily.
+server.upload-dirs = ( "/var/cache/lighttpd/uploads" )
+
+## where to send error-messages to
+server.errorlog = var.root-dir + "/default/logs/error.log"
+
+## files to check for if .../ is requested
+index-file.names = ( "index.php", "index.html" )
+
+#### accesslog module
+accesslog.filename = var.root-dir + "/default/logs/access.log"
+
+## deny access the file-extensions
+#
+# ~ is for backupfiles from vi, emacs, joe, ...
+# .inc is often used for code includes which should in general not be part
+# of the document-root
+url.access-deny = ( "~", ".inc" )
+
+##
+# which extensions should not be handle via static-file transfer
+#
+# .php, .pl, .fcgi are most often handled by mod_fastcgi or mod_cgi
+static-file.exclude-extensions = ( ".php", ".pl", ".fcgi" )
+
+## Use ipv6 only if available.
+server.use-ipv6 = "disable"
+
+## to help the rc.scripts
+server.pid-file = "/var/run/lighttpd.pid"
+
+## virtual directory listings
+dir-listing.encoding = "utf-8"
+# Disable dir-listing by default
+server.dir-listing = "disable"
+
+# Don't run as root
+server.username = "www-data"
+server.groupname = "www-data"
+
+#### external configuration files
+## mimetype mapping
+include_shell var.conf-dir + "/scripts/create-mime.assign.pl"
+
+## load vhosts
+include_shell var.conf-dir + "/scripts/include-vhosts.pl"
--- /dev/null
+#!/usr/bin/perl -w
+
+# This script is based on /usr/share/lighttpd/create-mime-assign.pl. This
+# script is changed to include a charset for text types.
+
+use strict;
+open MIMETYPES, "/etc/mime.types" or exit;
+print "mimetype.assign = (\n";
+my %extensions;
+while(<MIMETYPES>) {
+ chomp;
+ s/\#.*//;
+ next if /^\w*$/;
+ if(/^([a-z0-9\/+-.]+)\s+((?:[a-z0-9.+-]+[ ]?)+)$/) {
+ my $mime = $1; my $exts = $2;
+ # Append encoding for text formats
+ if ($mime =~ /^text\//) {
+ $mime .= "; charset=iso-8859-1";
+ }
+ foreach(split / /, $exts) {
+ # mime.types can have same extension for different
+ # mime types
+ next if $extensions{$_};
+ $extensions{$_} = 1;
+
+ print "\".$_\" => \"$mime\",\n";
+ }
+ }
+}
+print ")\n";
--- /dev/null
+#!/usr/bin/perl -wl
+
+# This script is based on /usr/share/lighttpd/include-conf-enabled.pl but
+# changed to read the vhosts directory instead of the conf-enabled directory.
+
+use strict;
+use File::Glob ':glob';
+
+my $confdir = "/etc/lighttpd/";
+my $enabled = "vhosts/*";
+
+chdir($confdir);
+my @files = bsd_glob($enabled);
+
+for my $file (@files)
+{
+ print "include \"$file\"";
+}
--- /dev/null
+$HTTP["host"] =~ "^(evolution-events.nl)$" {
+ url.redirect = (".*" => "http://www.%1/")
+}
+
+$HTTP["host"] =~ ".evolution-events.nl$" {
+ var.site-dir = var.root-dir + "/evolution-events.nl"
+ var.site-fcgi-dir = var.fcgi-dir + "/evolution-events-nl"
+
+ evhost.path-pattern = var.site-dir + "/htdocs/%3/"
+ accesslog.filename = var.site-dir + "/logs/access.log"
+
+ fastcgi.server = (
+ ".php" =>
+ ((
+ "socket" => var.site-fcgi-dir + "/php",
+ "broken-scriptfilename" => "enable",
+ )),
+ "/wipi" =>
+ ((
+ "socket" => var.site-fcgi-dir + "/wipi",
+ "check-local" => "disable",
+ "broken-scriptfilename" => "enable",
+ )),
+ )
+ alias.url = (
+ # Don't name this /wipistatic, since that will be caught by fastcgi above
+ "/staticwipi" => var.site-dir + "/applications/wipi/static/",
+ )
+
+ url.rewrite-once = (
+ "^/wipi/static/(.*)$" => "/staticwipi/$1",
+ "^(/.*)$" => "$1",
+ )
+
+ $HTTP["host"] =~ "^orga.evolution-events.nl$" {
+ auth.backend = "plain"
+ auth.backend.plain.userfile = var.site-dir + "/conf/simple.user"
+
+ auth.require = ( "/private" =>
+ (
+ "method" => "digest",
+ "realm" => "Evolution Events",
+ "require" => "user=admin"
+ )
+ )
+
+
+ url.rewrite-once = (
+ "^/forum/(.+)$" => "/forum/",
+ )
+ }
+
+ $HTTP["host"] =~ "^xerxes.evolution-events.nl$" {
+ fastcgi.server = (
+ "/blaa" =>
+ ((
+ "socket" => var.site-fcgi-dir + "/xerxes",
+ "check-local" => "disable",
+ )),
+ )
+
+ alias.url = (
+ "/media/" => "/home/matthijs/django/contrib/admin/media/",
+ "/static/" => var.site-dir + "/applications/xerxes/static/",
+ )
+
+ url.rewrite-once = (
+ "^(/media.*)$" => "$1",
+ "^(/static.*)$" => "$1",
+ "^/favicon\.ico$" => "/media/favicon.ico",
+ "^(/.*)$" => "/blaa$1",
+ )
+ }
+}
--- /dev/null
+$HTTP["host"] =~ ".foresightsecurity.nl$" {
+ var.site-dir = var.root-dir + "/foresightsecurity.nl"
+ var.site-fcgi-dir = var.fcgi-dir + "/evolution-events-nl"
+
+ evhost.path-pattern = var.site-dir + "/htdocs/%3/"
+ accesslog.filename = var.site-dir + "/logs/access.log"
+
+ fastcgi.server = (
+ ".php" =>
+ ((
+ "socket" => var.site-fcgi-dir + "/php",
+ "broken-scriptfilename" => "enable",
+ ))
+ )
+
+ cgi.assign = ( "cgi" => "" )
+}
--- /dev/null
+$HTTP["host"] =~ ".stderr.nl$" {
+ var.site-dir = var.root-dir + "/stderr.nl"
+ var.site-fcgi-dir = var.fcgi-dir + "/stderr-nl"
+
+ evhost.path-pattern = var.site-dir + "/htdocs/%3/"
+ accesslog.filename = var.site-dir + "/logs/access.log"
+
+ fastcgi.server = (
+ ".php" =>
+ ((
+ "socket" => var.site-fcgi-dir + "/php",
+ "broken-scriptfilename" => "enable",
+ ))
+ )
+
+ cgi.assign = ( "cgi" => "" )
+
+ $HTTP["host"] =~ "git.stderr.nl$" {
+ # Put this alias in a url conditional, so urls like /gitweb.css won't get alias'd
+ $HTTP["url"] =~ "^/gitweb(/.*)?$" {
+ alias.url += ( "/gitweb" => "/usr/lib/cgi-bin/gitweb.cgi" )
+ }
+ }
+
+ $HTTP["host"] =~ "indigetes.stderr.nl$" {
+ auth.backend = "htpasswd"
+ auth.backend.htpasswd.userfile = var.site-dir + "/pandora2008.user"
+
+ auth.require = (
+ "/" => (
+ "method" => "basic",
+ "realm" => "Di Indigetes",
+ "require" => "valid-user"
+ )
+ )
+ }
+}
--- /dev/null
+$HTTP["host"] =~ ".stdin.nl$" {
+ var.site-dir = var.root-dir + "/stdin.nl"
+ var.site-fcgi-dir = var.fcgi-dir + "/stdin-nl"
+
+ evhost.path-pattern = var.site-dir + "/htdocs/%3/"
+ accesslog.filename = var.site-dir + "/logs/access.log"
+
+ fastcgi.server = ( ".php" =>
+ ((
+ "socket" => var.site-fcgi-dir + "/php",
+ "broken-scriptfilename" => "enable",
+ ))
+ )
+}
--- /dev/null
+$HTTP["host"] =~ "stdio.flexvps.nl$" {
+ var.site-dir = var.root-dir + "/stdio.flexvps.nl"
+ var.site-fcgi-dir = var.fcgi-dir + "/stdio-flexvps-nl"
+
+ server.document-root = var.site-dir + "/htdocs"
+ accesslog.filename = var.site-dir + "/logs/access.log"
+
+ fastcgi.server = (
+ ".php" =>
+ ((
+ "socket" => var.site-fcgi-dir + "/php",
+ "broken-scriptfilename" => "enable",
+ ))
+ )
+}
--- /dev/null
+$HTTP["host"] =~ ".stdout.nl$" {
+ var.site-dir = var.root-dir + "/stdout.nl"
+ var.site-fcgi-dir = var.fcgi-dir + "/stdout-nl"
+
+ evhost.path-pattern = var.site-dir + "/htdocs/%3/"
+ accesslog.filename = var.site-dir + "/logs/access.log"
+
+ fastcgi.server = ( ".php" =>
+ ((
+ "socket" => var.site-fcgi-dir + "/php",
+ ))
+ )
+}
--- /dev/null
+#!/bin/sh
+exec perl -mfiletest=access $@
--- /dev/null
+#!/bin/sh
+
+if [ "$1" = "-h" -o "$1" = "--help" -o $# -ne 1 ]; then
+ echo "Usage $0 <dirname>"
+ echo "<dirname> is the full path to the site, such as /var/www/example.nl"
+ echo "which is created if it does not exist yet. If it exists, it's"
+ echo "permissions are reset".
+ exit 0
+fi
+
+HTTPD_USER=www-data
+# The primary group of the created user
+HTTPD_USERS_GID=1002
+# The template to copy
+TEMPLATE_DIR=/data/www/template
+# The bases to create users under
+USERBASE=ou=Users,dc=drsnuggles,dc=stderr,dc=nl
+GROUPBASE=ou=Groups,dc=drsnuggles,dc=stderr,dc=nl
+# PHP config to change the error_log setting in
+PHP_CONFIG=conf/php.ini.override
+# PHP error logfile to set error_log to
+PHP_ERRORLOG=logs/php.log
+
+# Get dir, but make it absolute
+cd "$1"
+DIR=`pwd`
+
+
+if [ -e "$DIR" -a ! -d "$DIR" ]; then
+ echo "$DIR" must be a directory, or not exist yet.
+ exit 1;
+fi
+
+# Strip prefix
+SITE=`basename $DIR`
+
+# replace . with -
+GROUP=`echo $SITE | sed s/\\\\./-/g`
+SCRIPT_USER="httpd-$GROUP"
+
+if getent passwd | grep $SCRIPT_USER &> /dev/null && getent group | grep $GROUP &> /dev/null; then
+ echo "$SCRIPT_USER and/or $GROUP already exists, skipping account creation"
+else
+ # find a uid
+ ID=2000
+ while getent passwd | cut -f 3 -d: | grep "^$ID\$" &>/dev/null && getent group | cut -f 3 -d: | grep "^$ID\$" &> /dev/null; do
+ ((ID++))
+ done;
+
+ echo Found uid/gid $ID for $SCRIPT_USER/$GROUP
+
+ # Create a user for scripts to run as, and a group to give write permissions to
+ # files.
+ ldapvi --profile bind --add --in --ldapvi <<EOF || exit
+add cn=$GROUP,$GROUPBASE
+cn: $GROUP
+gidNumber: $ID
+objectClass: posixGroup
+objectClass: top
+
+add cn=$SITE,$USERBASE
+cn: $SITE
+uidNumber: $ID
+gidNumber: $HTTPD_USERS_GID
+homeDirectory: $DIR
+objectClass: posixAccount
+objectClass: account
+objectClass: top
+uid: $SCRIPT_USER
+EOF
+fi
+
+if getent passwd | grep $SCRIPT_USER &> /dev/null && getent group | grep $GROUP &> /dev/null; then
+ echo "$SCRIPT_USER and $GROUP created succesfully"
+else
+ echo "User or group creation failed"
+ exit 1
+fi
+
+if [ -e "$DIR" ]; then
+ echo "Skipping creation of $DIR, it already exists";
+else
+ # Create $DIR from $TEMPLATE_DIR, if it does not exist yet
+ echo "Creating $DIR from $TEMPLATE_DIR"
+ cp -R "$TEMPLATE_DIR" "$DIR"
+fi
+
+echo "Setting up permissions"
+# Set up permissions
+sudo chown -R 0:$GROUP "$DIR"
+
+# By default, let the owner have write access, the group have read access
+sudo setfacl -R --set d:u::rwX,d:g::rX,d:o::-,u::rwX,g::rX,o::- "$DIR"
+
+# Give the group write access to htdocs, applications and conf
+sudo setfacl -R -m g::rwX "$DIR/htdocs" "$DIR/applications" "$DIR/conf"
+
+# Give lighttpd read access to the dir itself
+sudo setfacl -m u:$HTTPD_USER:rx "$DIR"
+
+# Allow lighttpd to read anything in htdocs, applications and conf
+sudo setfacl -R -m d:u:$HTTPD_USER:rX,u:$HTTPD_USER:rX "$DIR/htdocs" "$DIR/applications" "$DIR/conf"
+
+# Allow lighttpd to write new files in logs (but not touch existing or those created by lighttpd)
+sudo setfacl -m u:$HTTPD_USER:rwX "$DIR/logs"
+
+# Give scripts read access to the dir itself
+sudo setfacl -m u:$SCRIPT_USER:rx "$DIR"
+
+# Allow scripts to read anything in applications, htdocs and conf
+sudo setfacl -R -m d:u:$SCRIPT_USER:rX,u:$SCRIPT_USER:rX "$DIR/applications" "$DIR/htdocs" "$DIR/conf"
+
+# Allow scripts to create new files in logs and data (but not touch existing or those created by lighttpd)
+sudo setfacl -m u:$SCRIPT_USER:rwX "$DIR/logs" "$DIR/data"
+
+# Temp, chown existing log files
+sudo sh -c "chown -R $SCRIPT_USER \"$DIR\"/logs/php.log* \"$DIR\"/logs/wipi.log*"
+sudo sh -c "chown -R $HTTPD_USER \"$DIR\"/logs/access.log*"
+
+# Now, set the error_log setting in php.ini
+
+echo Updating `basename $PHP_CONFIG`
+
+sudo sed -i "s#^error_log *=.*#error_log = $DIR/$PHP_ERRORLOG#" "$DIR/$PHP_CONFIG"
+
+
+# Done!
+echo "Done!"
+echo "Now add human users to $GROUP."
+echo "Also add this site to /usr/local/sbin/spawn-fcgi.sh and enable"
+echo "fcgi in lighttpd if dynamic content is required."
--- /dev/null
+#!/bin/sh
+
+# This script will merge the main php.ini with local and site specific
+# additions into a site specific php.ini.
+
+BASE=/etc/php5/cgi/php.ini
+LOCAL=/etc/php5/cgi/php.ini.local
+SITES=/data/www/*
+CONFIN=conf/php.ini.override
+CONFOUT=conf/php.ini
+
+for SITE in $SITES; do
+ IN=$SITE/$CONFIN
+ OUT=$SITE/$CONFOUT
+ if [ \! -r $IN ]; then
+ continue;
+ fi
+ echo "Updating $OUT"
+
+ cat > $OUT <<EOF
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;
+; This file is autogenerated by $0
+;
+; Do NOT edit this file directly.
+;
+; You should instead edit $IN (for site-specific config) or $LOCAL (for global
+; config) and run $0 afterwards.
+;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+
+;;; Begin included $BASE (this is the default config from php) ;;;
+
+EOF
+
+ cat $BASE >> $OUT
+ echo -e "\n;;; End included $BASE ;;;\n" >> $OUT
+ echo -e "\n;;; Begin included $LOCAL (these are global config changes) ;;;\n" >> $OUT
+ cat $LOCAL >> $OUT
+ echo -e "\n;;; End included $LOCAL ;;;\n" >> $OUT
+ echo -e "\n;;; Begin included $IN (these are config changes specific to this site) ;;;\n" >> $OUT
+ cat $IN >> $OUT
+ echo -e "\n;;; End included $IN ;;;\n" >> $OUT
+done
--- /dev/null
+#!/usr/bin/env python
+#
+# An example CGI script to export multiple hgweb repos, edit as necessary
+
+# adjust python path if not a system-wide install:
+#import sys
+#sys.path.insert(0, "/path/to/python/lib")
+
+# enable importing on demand to reduce startup time
+from mercurial import demandimport; demandimport.enable()
+
+# Uncomment to send python tracebacks to the browser if an error occurs:
+#import cgitb
+#cgitb.enable()
+
+# If you'd like to serve pages with UTF-8 instead of your default
+# locale charset, you can do so by uncommenting the following lines.
+# Note that this will cause your .hgrc files to be interpreted in
+# UTF-8 and all your repo files to be displayed using UTF-8.
+#
+#import os
+#os.environ["HGENCODING"] = "UTF-8"
+
+from mercurial.hgweb.hgwebdir_mod import hgwebdir
+import mercurial.hgweb.wsgicgi as wsgicgi
+
+# The config file looks like this. You can have paths to individual
+# repos, collections of repos in a directory tree, or both.
+#
+# [paths]
+# virtual/path = /real/path
+# virtual/path = /real/path
+#
+# [collections]
+# /prefix/to/strip/off = /root/of/tree/full/of/repos
+#
+# collections example: say directory tree /foo contains repos /foo/bar,
+# /foo/quux/baz. Give this config section:
+# [collections]
+# /foo = /foo
+# Then repos will list as bar and quux/baz.
+#
+# Alternatively you can pass a list of ('virtual/path', '/real/path') tuples
+# or use a dictionary with entries like 'virtual/path': '/real/path'
+
+application = hgwebdir('/etc/hgweb.conf')
+wsgicgi.launch(application)