<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Christopher Lawlor &#187; freelancing</title>
	<atom:link href="http://blog.christopherlawlor.com/tag/freelancing/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.christopherlawlor.com</link>
	<description>Adventures in Freelancing</description>
	<lastBuildDate>Thu, 18 Aug 2011 13:12:11 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Setting Up Client Mercurial Repositories</title>
		<link>http://blog.christopherlawlor.com/2010/05/multiple-mercurial-repositorie/</link>
		<comments>http://blog.christopherlawlor.com/2010/05/multiple-mercurial-repositorie/#comments</comments>
		<pubDate>Mon, 24 May 2010 19:31:31 +0000</pubDate>
		<dc:creator>clawlor</dc:creator>
				<category><![CDATA[Dev Tools]]></category>
		<category><![CDATA[freelancing]]></category>
		<category><![CDATA[hg]]></category>
		<category><![CDATA[mercurial]]></category>

		<guid isPermaLink="false">http://blog.christopherlawlor.com/?p=21</guid>
		<description><![CDATA[Hosting multiple mercurial repositories isn&#8217;t too tricky, there are various tutorials scattered around the web that will get you up and running. However, the security setups in these tutorials are somewhat lacking. This is particularly true if you need fine grained control over not only who gets to PUSH, but also who gets to PULL]]></description>
			<content:encoded><![CDATA[<p>Hosting multiple mercurial repositories isn&#8217;t too tricky, there are various tutorials <a href="http://docs.webfaction.com/software/mercurial.html" target="_blank">scattered</a> <a href="http://mercurial.selenic.com/wiki/HgWebDirStepByStep" target="_blank">around</a> the web that will get you up and running. However, the security setups in these tutorials are somewhat lacking. This is particularly true if you need fine grained control over not only who gets to PUSH, but also who gets to PULL from the repositories.</p>
<p>Our goal here is to host as many repositories as we&#8217;d like, but only allow client access on a per-repository basis. If I set up repository A for client A, I don&#8217;t want client A to be able to pull from repository B.</p>
<p>Let&#8217;s start by describing our starting point. . All of the tutorials I&#8217;ve found get you set up with something like this. We&#8217;ve installed mercurial somewhere, and copied the <code>hgwebdir.cgi</code> file to our webroot, and configured it with a <code>hgweb.config</code> file. </p>
<p>Also, there is an <code>.htaccess</code> file at the web root that both limits POST and PUT access to users specified in a password file <code>.htpasswd</code>, which is made with the <code>htpasswd</code> command.</p>
<pre class="brush: text">
# .htaccess file at webroot
Options +ExecCGI
RewriteEngine On
# / for root directory; specify a complete path from / for others
RewriteBase /
RewriteRule ^$ hgwebdir.cgi  [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) hgwebdir.cgi/$1  [QSA,L]

AuthType Basic
AuthName My Hg Repositories
AuthUserFile /path/to/webroot/.htpasswd
&lt;Limit POST PUT&gt;
Require valid-user
&lt;/Limit&gt;
</pre>
<p>The first portion routes all requests through the hgwebdir.cgi script, unless the request is for an existing file.</p>
<p>What we&#8217;re interested in is the second part. The tutorials go into the details, but in summary what is happening is that any POST or PUT requests will be authenticated using Basic authentication against the password file .htpasswd. This covers access to ALL the repositories.</p>
<p>There are a couple of problems here. First, with the .htaccess file above, our security related files are openly accessible to everyone. We can add a FilesMatch directive to hide our security files:</p>
<pre class="brush: text">
&lt;FilesMatch &quot;\.(htaccess|htpasswd|config|bak|ini)$&quot;&gt;
Order allow,deny
Deny from all
&lt;/FilesMatch&gt;
</pre>
<p>The second problem is that everyone can still see all of the repositories. Since these are client repos, I don&#8217;t want the random browser to stumble across them. That&#8217;s fixed easily enough, just change</p>
<pre class="brush: text">
&lt;Limit POST PUT&gt;
</pre>
<p>to</p>
<pre class="brush: text">
&lt;Limit POST PUT GET&gt;
</pre>
<p>Now ALL requests are met with a request for authentication. It&#8217;s not the prettiest thing in the world, but it works for now. Only clients in the .htpasswd file can view the web portal.</p>
<p>Now to configure access to the repositories themselves. Our security settings will go in each repository&#8217;s <code>hgrc</code>file. The two settings we are interested are <code>allow_push</code> and <code>allow_read</code>. Each take a comma-separated list of authorized users. These go in the [web] section of the configuration file.</p>
<pre class="brush: text">
[web]
allow_read = me,client1,client2
allow_push = me,client1
</pre>
<p>It&#8217;s worth noting that the default for <code>allow_read</code> is to allow all, but the default for <code>allow_push</code> is to deny all.</p>
<p>The major remaining limitation is that once I add a client to the <code>.htpasswd</code> file, they have access to the whole web interface, which lets them view other repositories. The solution is to add <code>hidden = true</code> to the <code>hgrc</file>. This hides the repository from the web directory listing at the root, which lists all of the available repos, but will still serve the repos' web page if accessed directly.</p>
<p>So with a repository 'test' set with <code>hidden = true</code>, it won't show up at <code>http://myreposerver/</code>, but it will still be visible at <code>http://myreposerver/test</code>.</p>
<p>To make it easy to add new repositories, I've created an 'empty' repository that already has an <code>hgrc</code> file configured pretty much the way I want. For reference, here's what I'm using:</p>
<pre class="brush: text">
[web]
contact = Chris Lawlor
description = Empty Mercurial Repository. Copy this to create client repos.

# Repository name to use in the web interface. Default is current working directory
#name =

## ACCESS CONTROL ##
allow_push = clawlor
allow_read = clawlor, fakeclient, fakeclient3

# hide repo from the directory
hidden = true
</pre>
<p>There are <a href="http://www.selenic.com/mercurial/hgrc.5.html#web">a lot of other settings</a> that can go into the <code>hgrc</code> file that control various aspects of the repository's presentation. Also, most or all of those settings can be made global by putting them in the <code>hgweb.config</code> file located at the webroot.</p>
<p>Now when I want a new repository, I can simple copy the 'empty' repository, change a few bits in the <code>hgrc</code> file, and add new users to the <code>.htpasswd</code> file.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.christopherlawlor.com/2010/05/multiple-mercurial-repositorie/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
<!-- This Quick Cache file was built for (  blog.christopherlawlor.com/tag/freelancing/feed/ ) in 0.18415 seconds, on Feb 6th, 2012 at 5:20 am UTC. -->
<!-- This Quick Cache file will automatically expire ( and be re-built automatically ) on Feb 6th, 2012 at 6:20 am UTC -->
