initial commit
authorroot <root@project-moonshot.org>
Wed, 9 Mar 2011 00:30:40 +0000 (19:30 -0500)
committerroot <root@project-moonshot.org>
Wed, 9 Mar 2011 00:30:40 +0000 (19:30 -0500)
.gitignore [new file with mode: 0644]
wiki/.ikiwiki/indexdb [new file with mode: 0644]
wiki/.ikiwiki/lockfile [new file with mode: 0644]
wiki/building.mdwn [new file with mode: 0644]
wiki/design.mdwn [new file with mode: 0644]
wiki/design/tlv.mdwn [new file with mode: 0644]
wiki/index.mdwn [new file with mode: 0644]
wiki/prepare.mdwn [new file with mode: 0644]
wiki/templates/page.tmpl [new file with mode: 0644]
wiki/wiki.conf [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..b84c806
--- /dev/null
@@ -0,0 +1,2 @@
+/.ikiwiki
+/recentchanges
diff --git a/wiki/.ikiwiki/indexdb b/wiki/.ikiwiki/indexdb
new file mode 100644 (file)
index 0000000..5d262ac
Binary files /dev/null and b/wiki/.ikiwiki/indexdb differ
diff --git a/wiki/.ikiwiki/lockfile b/wiki/.ikiwiki/lockfile
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/wiki/building.mdwn b/wiki/building.mdwn
new file mode 100644 (file)
index 0000000..d890693
--- /dev/null
@@ -0,0 +1,43 @@
+# Building moonshot
+First, make sure you have the following dependencies installed:
+
+1. [OpenSSL](http://www.openssl.org/)
+1. [Curl](http://curl.haxx.se)
+1. [XML Security](http://xml.apache.org/security/)
+1. Xerces XML parser
+1. [MIT Kerberos](http://web.mit.edu/kerberos/) at least version 1.9
+1. log4cpp or log4shibb
+1. [libevent](http://www.monkey.org/~provos/libevent/) at least
+version 2.0
+
+On a Debian or Ubuntu system you can get a lot of these dependencies
+with:
+
+    aptitude install libxml-security-c-dev libxerces-c-dev \
+      libcurl4-openssl-dev liblog4cpp5-dev
+
+A sufficiently new version of libevent is in the libevent-dev package
+in Debian experimental. The libkrb5-dev in Debian experimental is also
+sufficiently new. [Sam Hartman](http://www.launchpad.net/~hartmans)
+maintains sufficiently new krb5 for Ubuntu.
+
+Follow the
+[Repository](http://www.project-moonshot.org/developers/repository)
+instructions for checking out a copy of Moonshot At this writing, the
+following should be sufficient: 
+
+    git clone http://www.project-moonshot.org/git/moonshot.git
+    cd moonshot
+    git submodule init
+    git submodule update
+
+
+
+Create some directory that you have permission to write to. We'll
+assume this is /usr/local/moonshot. Run
+
+    ./builder --prefix=/usr/local/moonshot
+
+The builder script  takes other options to permit modifying what is
+passed to configure. The script will build and install the Moonshot
+projects. Now [[Prepare]] to use the software.
diff --git a/wiki/design.mdwn b/wiki/design.mdwn
new file mode 100644 (file)
index 0000000..c87f170
--- /dev/null
@@ -0,0 +1,4 @@
+# Design Discussions
+[[!toc startlevel=2]]
+
+[[!inline pages=design/* ]]
diff --git a/wiki/design/tlv.mdwn b/wiki/design/tlv.mdwn
new file mode 100644 (file)
index 0000000..ec1be93
--- /dev/null
@@ -0,0 +1,178 @@
+## Rationale for the TLV abstraction  
+
+hartmans: Luke, do you have opinions on what we want to do to the tokens for the target name stuff and SNI?  
+lukeh: will we be sending a bunch of arbitrary attributes like the acceptor does? like GSS-Asserted-Acceptor-Service-Name  
+lukeh: what's SNI?  
+hartmans: I think it means that the first token from initiator to acceptor (which I guess is useless today) probably wants to be a TLV token.  
+lukeh: yeah, I followed that on the mailing list but didn't implement as I was busy with other stuff  
+lukeh: that sounds reasonable, I guess it would require some reorganisation  
+lukeh: why do we want to send the target name?  
+hartmans: If you're getting a target name back then you probably want a TLV token for the first acceptor to initiator. But today that also includes an eap identity request, right?  
+lukeh: yes  
+hartmans: The question is do we want to TLV all the EAP tokens at that point?  
+lukeh: hmm.  
+lukeh: well either way I guess has merit  
+hartmans: The down side of TLVing everything is that then you can have news ways of having mallformed tokens.  
+lukeh: but I probably need to understand things better  
+lukeh: why does the acceptor send the target name back?  
+lukeh: I'm starting from a point of not understanding what is wrong with the existing protocol :)  
+hartmans: OK, so there are two different usages.  
+lukeh: as my understanding is we get the acceptor name back anyway in the EAP CB attributes  
+hartmans: 1) server name indication: the initiator knows the target name, but the acceptor may server multiple names.  
+hartmans: Here, the acceptor wants to know what name the initiator is calling.  
+***hartmans needs to think through the gss implications of what names the server accepts with Nico  
+hartmans: The other usage is null target name: the initiator doesn't know the target name but will look at the target name in the established context and see if it likes it.  
+hartmans: However in our mechanism, the initiator needs to learn the target name early so it can channel bind to it in EAP so it actually can believe the result.  
+hartmans: No, we don't get the acceptor name back in the eap CB.  
+hartmans: We *send* it in the eap cb and get back an indication about whether the server considered it in the CB result.  
+lukeh: ah.  
+hartmans: We don't get the value back.  
+hartmans: The other thing I'm wondering.  
+hartmans: Is there any actual information in the eap identity request?  
+hartmans: Could we just fake that packet and save a round trip?  
+lukeh: hmm, good point  
+Josh: we need the realm for routing  
+lukeh: that's in the response, not the request.  
+hartmans: That's in the identity response, right?  
+Josh: oh I mis-read  
+lukeh: yeah, Sam, that's an interesting point  
+lukeh: it didn't occur to me to do that  
+Josh: that would be a violation of the EAP SM, no?  
+lukeh: possibly  
+lukeh: I mean, the initiator would generate it itself rather than getting it from the acceptor  
+lukeh: certainly it's easier to understand in the current protocol  
+lukeh: but whether it's not worth optimising away is another question.  
+hartmans: Josh, it all depends on where you draw the layers.  
+Josh: take your point  
+hartmans: Note that on the radius server, the EAP SM never generates that packet... The NAS generates that one, right?  
+Josh: right  
+hartmans: I'm arguing we're basically doing the same thing. Rather than having the NAs generate that, we're asking the client to generate that and feed it to its own state machine.  
+hartmans: That only works if the packet is content free.  
+Josh: what's the advantage to that?  
+lukeh: save a roundtrip  
+lukeh: because currently the initiator sends an empty token  
+lukeh: just to poke things into action  
+Josh: IIRC, the data field can be used in the EAP-Identity/Request, but rarely is.  
+lukeh: hmm, if we are optimising something away that might be useful  
+hartmans: If it is used, what's it used for.  
+lukeh: then that may be bad.  
+hartmans: Sadly, Jari is not online. (He's the obvious eap expert in my buddy list)  
+Josh: I think we have previously floated the idea of using that data field for federation selection  
+lukeh: heh, can we shove the acceptor name in there  
+hartmans: Josh, I think that the changes we're talking about for target name null and for sni will give us the rope we need for federation selection.  
+***hartmans will investigate what that's useful for.  
+lukeh: please define SNI  
+lukeh: server name indication  
+lukeh: ?  
+Josh: True, and cleaner I believe.  
+hartmans: Luke if you're going to have an opinion on what tokens should be TLVed, please do so preferably before IETF.  
+hartmans: yes  
+  
+## Actual Design of resulting TLV implementation  
+  
+lukeh: OK, so the TLV code runs on a table of ( input token, output token, valid states, flags, callback )  
+lukeh: there are still a few too many special cases to be completely in love with it  
+lukeh: but hopefully after a few more days of hacking it will get there  
+lukeh: I've added some debug tokens in the initial leg to test that that works  
+lukeh: the previous extension tokens (GSS CB, reauth) are now just, obviously, TLVs in the last leg  
+lukeh: there is now only one *GSS* token for context establishment, TOK_TYPE_ESTABLISH_CONTEXT  
+lukeh: and a bunch of "inner" token types  
+lukeh: #define ITOK_TYPE_CONTEXT_ERR           0x00000001  
+    #define ITOK_TYPE_ACCEPTOR_NAME_REQ     0x00000002  
+    #define ITOK_TYPE_ACCEPTOR_NAME_RESP    0x00000003  
+    #define ITOK_TYPE_EAP_RESP              0x00000004  
+    #define ITOK_TYPE_EAP_REQ               0x00000005  
+    #define ITOK_TYPE_GSS_CHANNEL_BINDINGS  0x00000006  
+    #define ITOK_TYPE_REAUTH_CREDS          0x00000007  
+    #define ITOK_TYPE_REAUTH_REQ            0x00000008  
+    #define ITOK_TYPE_REAUTH_RESP           0x00000009  
+    #define ITOK_TYPE_VERSION_INFO          0x0000000A  
+    #define ITOK_TYPE_VENDOR_INFO           0x0000000B  
+    #define ITOK_FLAG_CRITICAL              0x80000000  /* critical, wire flag */  
+  
+lukeh: s/last leg/last round trip/  
+hartmans: What do you mean by token types in the table?  
+hartmans: Do you mean that a given callback can only produce one output token type, or something more than that?  
+lukeh: a given callback can only produce one output token type  
+lukeh: true, a callback could have returned a set of tokens  
+lukeh: perhaps that would be desirable  
+lukeh: but as long as the state can be passed through the context or credential object  
+lukeh: the same effect can be achieved  
+hartmans: I think that simplicity is good for now.  
+hartmans: OK, that implementation makes sense.  
+lukeh: the trunk is simplicity :-)  
+lukeh: although one nice thing is that the state machine walker is now shared between initiator and acceptor.  
+lukeh: so I may have reduced the line count actually.  
+lukeh: meh, about the same.  
+hartmans: So, can a callback return success and no token?  
+lukeh: yeah.  
+hartmans: good.  
+lukeh: (well, CONTINUE, or COMPLETE)  
+lukeh: I needed that for a couple of cases.  
+lukeh: first, if you transit states and don't emit a token  
+hartmans: and anyone returning continue means overall result is continue?  
+hartmans: anyone returning error means overall result is error?  
+lukeh: (hang on)  
+lukeh: e.g. going from completing the EAP stage (if no token emitted) to the extension stage  
+hartmans: Does that produce a round-trip or does it simply re-run the packet in the new state combining the output?  
+lukeh: (I'm going to answer your questions in order asked)  
+hartmans: That (state transition) was the case that was making me think you'd need the no token logic  
+lukeh: also, if you have a set of optional tokens (e.g. extensions) you need something to mark the end and transit the state.  
+hartmans: Yes, answering in order asked is fine.  
+lukeh: The very final callback that marks the context established returns COMPLETE  
+lukeh: Others return CONTINUE on success or an error.  
+lukeh: Returning an error means the overall result is an error and, on the acceptor side, an error token may be generated (this is done at the state machine layer)  
+lukeh: In case of a state transition when there is no output token, then the next set of callbacks are called with no input token  
+lukeh: to avoid regurgitating the input token from the previous state  
+hartmans: OK that last is non-obvious to me (calling nwith no input token)  
+lukeh: so, basically, tokens are emitted to the peer  
+hartmans: Can I see the table? It might be more clear there.  
+lukeh: when we've run out of callbacks or we transit states and have a token to send  
+lukeh: (more or less, there are a couple of exceptions to handle things like sending no tokens on the initial context token in order to poke the acceptor into sending us an EAP request)  
+lukeh: (rather than sending an empty EAP response from the initiator, as semantically that did not seem correct)  
+lukeh: (although perhaps it is, who knows.)  
+lukeh: if you checkout tlv  
+lukeh: look for eapGssInitiatorSm in init_sec_context.c  
+lukeh: and the corresponding one for the acceptor.  
+lukeh: note: the states are bitmasks.  
+lukeh: there's some verbose commenting in init_sm.c too.  
+hartmans: Ah, that makes so much more sense from the table  
+hartmans: This is quite clever.  
+lukeh: Hmm, it still doesn't feel *quite* right. Too many exceptions. I suspect if that if I was doing it from scratch rather than refactoring it might look different. But, it seems to work for now. Will revise over coming days.  
+lukeh: I think it is ugly because it collapses the state and token dimensions into a single one.  
+lukeh: However it does make it easier to have tokens that support multiple states.  
+lukeh: Although there are some limitations with that (the dispatch table is not retraversed after a state change so it effectively only works for exception tokens; of course, that's easily fixed)  
+hartmans: So, we depend on the EAP machine keeping us in sync between the initiator and acceptor?  
+hartmans: Not a problem, just confirming I understand.  
+hartmans: What do you mean state and token are combined? They are separate columns in the table as far as I can tell  
+lukeh: it's not a 2 dimensional array.  
+lukeh: they are separate columns yes  
+lukeh: re: depending on the EAP machine  
+hartmans: Ah.  
+lukeh: yes, I guess we do, what else could one do?  
+lukeh: it's a black box  
+lukeh: I don't know what happens yet if the EAP machine emits a token on success, I don't think that's possible though  
+lukeh: I need to check  
+***hartmans has too much of a relational database mindset to think of that as more than an efficiency issue  
+lukeh: yeah, I never used relational databases, so I never had that mindset  
+hartmans: I think depending on EAP to be consistent is fine.  
+hartmans: We could actually echo the eap state in some sort of market token. That would be far far worse.  
+lukeh: So, adding a new token that doesn't change the state is fairly easy.  
+lukeh: You just need to be careful where you put it in the table  :)  
+lukeh: It needs to be before the state changing entry.  
+lukeh: You can set the critical/required flags as desired.  
+lukeh: Some care is likely necessary to avoid colliding with the reauthentication path. But I think that's fairly easy.  
+lukeh: In my initial implementation I had overloaded the GSS status codes to mean various things, but in the end that got quite ugly.  
+lukeh: So I went with the callbacks performing the state changes themselves plus a flag to indicate a few exceptional things (e.g. get-out now)  
+hartmans: Presumably error always means get out now?  
+lukeh: yes  
+lukeh: if you want to get out now on CONTINUE, you need to either  
+lukeh: a) change state and emit a token  
+lukeh: b) change state and set FORCE_SEND_TOKEN (this is used to handle the initial case where we poke the acceptor without sending an inner token)  
+lukeh: c) set STOP_EVAL - this is not used yet  
+lukeh: the above applies to COMPLETE as well as CONTINUE  
+lukeh: there are some sanity checks to make sure COMPLETE only happens when state becomes ESTABLISHED  
+lukeh: see SM_ASSERT_VALID  
+hartmans: OK, and we can remove an exception if we decide it's OK for us to fake the eap request identity  
+lukeh: ah yes  
+hartmans: This is really cool.  
diff --git a/wiki/index.mdwn b/wiki/index.mdwn
new file mode 100644 (file)
index 0000000..b2d2e81
--- /dev/null
@@ -0,0 +1,6 @@
+# Moonshot Developer Wiki
+
+This is a wiki for those working on or using the Moonshot code base.
+
+* [[Building]] Moonshot
+* [[Design]] Discussions
diff --git a/wiki/prepare.mdwn b/wiki/prepare.mdwn
new file mode 100644 (file)
index 0000000..a239733
--- /dev/null
@@ -0,0 +1,10 @@
+# Preparing to use Moonshot
+
+First, look at the mech file in the mech_eap directory of the source
+tree. Copy this file to /etc/gss/mech and change the location of
+mech_eap.so to be correct for your installation.
+
+Todo:
+* configure libradsec
+* Set up RADIUS
+
diff --git a/wiki/templates/page.tmpl b/wiki/templates/page.tmpl
new file mode 100644 (file)
index 0000000..0682a74
--- /dev/null
@@ -0,0 +1,197 @@
+<TMPL_IF HTML5><!DOCTYPE html>
+<html>
+<TMPL_ELSE><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+</TMPL_IF>
+<head>
+<TMPL_IF DYNAMIC>
+<TMPL_IF FORCEBASEURL><base href="<TMPL_VAR FORCEBASEURL>" /><TMPL_ELSE>
+<TMPL_IF BASEURL><base href="<TMPL_VAR BASEURL>" /></TMPL_IF>
+</TMPL_IF>
+</TMPL_IF>
+<TMPL_IF HTML5><meta charset="utf-8" /><TMPL_ELSE><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></TMPL_IF>
+<title><TMPL_VAR TITLE></title>
+<TMPL_IF FAVICON>
+<link rel="icon" href="<TMPL_VAR BASEURL><TMPL_VAR FAVICON>" type="image/x-icon" />
+</TMPL_IF>
+<link rel="stylesheet" href="<TMPL_VAR BASEURL>style.css" type="text/css" />
+<TMPL_IF LOCAL_CSS>
+<link rel="stylesheet" href="<TMPL_VAR BASEURL><TMPL_VAR LOCAL_CSS>" type="text/css" />
+<TMPL_ELSE>
+<link rel="stylesheet" href="<TMPL_VAR BASEURL>local.css" type="text/css" />
+</TMPL_IF>
+<TMPL_IF EDITURL>
+<link rel="alternate" type="application/x-wiki" title="Edit this page" href="<TMPL_VAR EDITURL>" />
+</TMPL_IF>
+<TMPL_IF FEEDLINKS><TMPL_VAR FEEDLINKS></TMPL_IF>
+<TMPL_IF RELVCS><TMPL_VAR RELVCS></TMPL_IF>
+<TMPL_IF META><TMPL_VAR META></TMPL_IF>
+</head>
+<body>
+
+<TMPL_IF HTML5><article class="page"><TMPL_ELSE><div class="page"></TMPL_IF>
+
+<TMPL_IF HTML5><section class="pageheader"><TMPL_ELSE><div class="pageheader"></TMPL_IF>
+<TMPL_IF HTML5><header class="header"><TMPL_ELSE><div class="header"></TMPL_IF>
+<span>
+<span class="parentlinks">
+<a href="http://www.project-moonshot.org/">Moonshot</a> <a href="http://www.project-moonshot.org/developers/">Developers</a> 
+<TMPL_LOOP PARENTLINKS>
+<a href="<TMPL_VAR URL>"><TMPL_VAR PAGE></a>/ 
+</TMPL_LOOP>
+</span>
+<span class="title">
+<TMPL_VAR TITLE>
+<TMPL_IF ISTRANSLATION>
+&nbsp;(<TMPL_VAR PERCENTTRANSLATED>%)
+</TMPL_IF>
+</span>
+</span>
+<TMPL_IF SEARCHFORM>
+<TMPL_VAR SEARCHFORM>
+</TMPL_IF>
+<TMPL_IF HTML5></header><TMPL_ELSE></div></TMPL_IF>
+
+<TMPL_IF HAVE_ACTIONS>
+<TMPL_IF HTML5><nav class="actions"><TMPL_ELSE><div class="actions"></TMPL_IF>
+<ul>
+<TMPL_IF EDITURL>
+<li><a href="<TMPL_VAR EDITURL>" rel="nofollow">Edit</a></li>
+</TMPL_IF>
+<TMPL_IF RECENTCHANGESURL>
+<li><a href="<TMPL_VAR RECENTCHANGESURL>">RecentChanges</a></li>
+</TMPL_IF>
+<TMPL_IF HISTORYURL>
+<li><a href="<TMPL_VAR HISTORYURL>">History</a></li>
+</TMPL_IF>
+<TMPL_IF GETSOURCEURL>
+<li><a href="<TMPL_VAR GETSOURCEURL>">Source</a></li>
+</TMPL_IF>
+<TMPL_IF PREFSURL>
+<li><a href="<TMPL_VAR PREFSURL>">Preferences</a></li>
+</TMPL_IF>
+<TMPL_IF ACTIONS>
+<TMPL_LOOP ACTIONS>
+<li><TMPL_VAR ACTION></li>
+</TMPL_LOOP>
+</TMPL_IF>
+<TMPL_IF COMMENTSLINK>
+<li><TMPL_VAR COMMENTSLINK></li>
+<TMPL_ELSE>
+<TMPL_IF DISCUSSIONLINK>
+<li><TMPL_VAR DISCUSSIONLINK></li>
+</TMPL_IF>
+</TMPL_IF>
+</ul>
+<TMPL_IF HTML5></nav><TMPL_ELSE></div></TMPL_IF>
+</TMPL_IF>
+
+<TMPL_IF OTHERLANGUAGES>
+<TMPL_IF HTML5><nav id="otherlanguages"><TMPL_ELSE><div id="otherlanguages"></TMPL_IF>
+<ul>
+<TMPL_LOOP OTHERLANGUAGES>
+<li>
+<a href="<TMPL_VAR URL>"><TMPL_VAR LANGUAGE></a>
+<TMPL_IF MASTER>
+(master)
+<TMPL_ELSE>
+&nbsp;(<TMPL_VAR PERCENT>%)
+</TMPL_IF>
+</li>
+</TMPL_LOOP>
+</ul>
+<TMPL_IF HTML5></nav><TMPL_ELSE></div></TMPL_IF>
+</TMPL_IF>
+
+<TMPL_IF HTML5></section><TMPL_ELSE></div></TMPL_IF>
+
+<TMPL_IF SIDEBAR>
+<TMPL_IF HTML5><aside class="sidebar"><TMPL_ELSE><div class="sidebar"></TMPL_IF>
+<TMPL_VAR SIDEBAR>
+<TMPL_IF HTML5></aside><TMPL_ELSE></div></TMPL_IF>
+</TMPL_IF>
+
+<div id="pagebody">
+
+<TMPL_IF HTML5><section id="content"><TMPL_ELSE><div id="content"></TMPL_IF>
+<TMPL_VAR CONTENT>
+<TMPL_IF HTML5></section><TMPL_ELSE></div></TMPL_IF>
+
+<TMPL_UNLESS DYNAMIC>
+<TMPL_IF COMMENTS>
+<TMPL_IF HTML5><section id="comments"><TMPL_ELSE><div id="comments"></TMPL_IF>
+<TMPL_VAR COMMENTS>
+<TMPL_IF ADDCOMMENTURL>
+<div class="addcomment">
+<a href="<TMPL_VAR ADDCOMMENTURL>">Add a comment</a>
+</div>
+<TMPL_ELSE>
+<div class="addcomment">Comments on this page are closed.</div>
+</TMPL_IF>
+<TMPL_IF HTML5></section><TMPL_ELSE></div></TMPL_IF>
+</TMPL_IF>
+</TMPL_UNLESS>
+
+</div>
+
+<TMPL_IF HTML5><footer id="footer" class="pagefooter"><TMPL_ELSE><div id="footer" class="pagefooter"></TMPL_IF>
+<TMPL_UNLESS DYNAMIC>
+<TMPL_IF HTML5><nav id="pageinfo"><TMPL_ELSE><div id="pageinfo"></TMPL_IF>
+
+<TMPL_IF TAGS>
+<TMPL_IF HTML5><nav class="tags"><TMPL_ELSE><div class="tags"></TMPL_IF>
+Tags:
+<TMPL_LOOP TAGS>
+<TMPL_VAR LINK>
+</TMPL_LOOP>
+<TMPL_IF HTML5></nav><TMPL_ELSE></div></TMPL_IF>
+</TMPL_IF>
+
+<TMPL_IF BACKLINKS>
+<TMPL_IF HTML5><nav id="backlinks"><TMPL_ELSE><div id="backlinks"></TMPL_IF>
+Links:
+<TMPL_LOOP BACKLINKS>
+<a href="<TMPL_VAR URL>"><TMPL_VAR PAGE></a>
+</TMPL_LOOP>
+<TMPL_IF MORE_BACKLINKS>
+<span class="popup">...
+<span class="balloon">
+<TMPL_LOOP MORE_BACKLINKS>
+<a href="<TMPL_VAR URL>"><TMPL_VAR PAGE></a>
+</TMPL_LOOP>
+</span>
+</span>
+</TMPL_IF>
+<TMPL_IF HTML5></nav><TMPL_ELSE></div></TMPL_IF>
+</TMPL_IF>
+
+<TMPL_IF COPYRIGHT>
+<div class="pagecopyright">
+<a name="pagecopyright"></a>
+<TMPL_VAR COPYRIGHT>
+</div>
+</TMPL_IF>
+
+<TMPL_IF LICENSE>
+<div class="pagelicense">
+<a name="pagelicense"></a>
+License: <TMPL_VAR LICENSE>
+</div>
+</TMPL_IF>
+
+<div class="pagedate">
+Last edited <TMPL_VAR MTIME>
+<!-- Created <TMPL_VAR CTIME> -->
+</div>
+
+<TMPL_IF HTML5></nav><TMPL_ELSE></div></TMPL_IF>
+<TMPL_IF EXTRAFOOTER><TMPL_VAR EXTRAFOOTER></TMPL_IF>
+</TMPL_UNLESS>
+<!-- from <TMPL_VAR WIKINAME> -->
+<TMPL_IF HTML5></footer><TMPL_ELSE></div></TMPL_IF>
+
+<TMPL_IF HTML5></article><TMPL_ELSE></div></TMPL_IF>
+
+</body>
+</html>
diff --git a/wiki/wiki.conf b/wiki/wiki.conf
new file mode 100644 (file)
index 0000000..638a96f
--- /dev/null
@@ -0,0 +1,310 @@
+#!/usr/bin/perl
+#
+# Setup file for ikiwiki.
+# 
+# Passing this to ikiwiki --setup will make ikiwiki generate
+# wrappers and build the wiki.
+# 
+# Remember to re-run ikiwiki --setup any time you edit this file.
+use IkiWiki::Setup::Standard {
+       # name of the wiki
+       wikiname => 'Moonshot Developer Wiki',
+       # contact email for wiki
+       adminemail => 'moonshot-community@jiscmail.ac.uk',
+       # users who are wiki admins
+       adminuser => [],
+       # users who are banned from the wiki
+       banned_users => [],
+       # where the source of the wiki is located
+       srcdir => '.',
+       # where to build the wiki
+       destdir => '../wiki-out',
+       # base url to the wiki
+       url => '',
+       # url to the ikiwiki.cgi
+       cgiurl => '',
+       # filename of cgi wrapper to generate
+       cgi_wrapper => '',
+       # mode for cgi_wrapper (can safely be made suid)
+       cgi_wrappermode => '06755',
+       # rcs backend to use
+       rcs => 'git',
+       # plugins to add to the default configuration
+       add_plugins => ['toc'],
+       # plugins to disable
+       disable_plugins => [],
+       # additional directory to search for template files
+       templatedir => '/usr/share/ikiwiki/templates',
+       # base wiki source location
+       underlaydir => '/usr/share/ikiwiki/basewiki',
+       # display verbose messages?
+       #verbose => 1,
+       # log to syslog?
+       #syslog => 1,
+       # create output files named page/index.html?
+       usedirs => 1,
+       # use '!'-prefixed preprocessor directives?
+       prefix_directives => 1,
+       # use page/index.mdwn source files
+       indexpages => 0,
+       # enable Discussion pages?
+       discussion => 1,
+       # name of Discussion pages
+       discussionpage => 'Discussion',
+       # generate HTML5? (experimental)
+       html5 => 0,
+       # only send cookies over SSL connections?
+       sslcookie => 0,
+       # extension to use for new pages
+       default_pageext => 'mdwn',
+       # extension to use for html files
+       htmlext => 'html',
+       # strftime format string to display date
+       timeformat => '%c',
+       # UTF-8 locale to use
+       #locale => 'en_US.UTF-8',
+       # put user pages below specified page
+       userdir => '',
+       # how many backlinks to show before hiding excess (0 to show all)
+       numbacklinks => 10,
+       # attempt to hardlink source files? (optimisation for large files)
+       hardlink => 0,
+       # force ikiwiki to use a particular umask
+       #umask => 022,
+       # group for wrappers to run in
+       #wrappergroup => 'ikiwiki',
+       # extra library and plugin directory
+       libdir => '',
+       # environment variables
+       ENV => {},
+       # regexp of normally excluded files to include
+       #include => '^\\.htaccess$',
+       # regexp of files that should be skipped
+       #exclude => '^(*\\.private|Makefile)$',
+       # specifies the characters that are allowed in source filenames
+       wiki_file_chars => '-[:alnum:]+/.:_',
+       # allow symlinks in the path leading to the srcdir (potentially insecure)
+       allow_symlinks_before_srcdir => 0,
+
+       ######################################################################
+       # core plugins
+       #   (editpage, htmlscrubber, inline, link, meta, parentlinks)
+       ######################################################################
+
+       # htmlscrubber plugin
+       # PageSpec specifying pages not to scrub
+       #htmlscrubber_skip => '!*/Discussion',
+
+       # inline plugin
+       # enable rss feeds by default?
+       #rss => 0,
+       # enable atom feeds by default?
+         atom => 1,
+       # allow rss feeds to be used?
+       #allowrss => 0,
+       # allow atom feeds to be used?
+       allowatom => 1,
+       # urls to ping (using XML-RPC) on feed update
+       pingurl => [],
+
+       ######################################################################
+       # auth plugins
+       #   (anonok, blogspam, httpauth, lockedit, moderatedcomments,
+       #    opendiscussion, openid, passwordauth, signinedit)
+       ######################################################################
+
+       # anonok plugin
+       # PageSpec to limit which pages anonymous users can edit
+       #anonok_pagespec => '*/discussion',
+
+       # blogspam plugin
+       # PageSpec of pages to check for spam
+       #blogspam_pagespec => 'postcomment(*)',
+       # options to send to blogspam server
+       #blogspam_options => 'blacklist=1.2.3.4,blacklist=8.7.6.5,max-links=10',
+       # blogspam server XML-RPC url
+       #blogspam_server => '',
+
+       # httpauth plugin
+       # url to redirect to when authentication is needed
+       #cgiauthurl => 'http://example.com/wiki/auth/ikiwiki.cgi',
+       # PageSpec of pages where only httpauth will be used for authentication
+       #httpauth_pagespec => '!*/Discussion',
+
+       # lockedit plugin
+       # PageSpec controlling which pages are locked
+       #locked_pages => '!*/Discussion',
+
+       # moderatedcomments plugin
+       # PageSpec matching users or comment locations to moderate
+       #moderate_pagespec => '*',
+
+       # openid plugin
+       # url pattern of openid realm (default is cgiurl)
+       #openid_realm => '',
+       # url to ikiwiki cgi to use for openid authentication (default is cgiurl)
+       #openid_cgiurl => '',
+
+       # passwordauth plugin
+       # a password that must be entered when signing up for an account
+       #account_creation_password => 's3cr1t',
+       # cost of generating a password using Authen::Passphrase::BlowfishCrypt
+       #password_cost => 8,
+
+       ######################################################################
+       # format plugins
+       #   (creole, highlight, hnb, html, mdwn, otl, rawhtml, textile, txt)
+       ######################################################################
+
+       # highlight plugin
+       # types of source files to syntax highlight
+       #tohighlight => '.c .h .cpp .pl .py Makefile:make',
+
+       # mdwn plugin
+       # enable multimarkdown features?
+       #multimarkdown => 0,
+
+       ######################################################################
+       # misc plugins
+       #   (filecheck)
+       ######################################################################
+
+       ######################################################################
+       # web plugins
+       #   (404, attachment, comments, editdiff, edittemplate, getsource,
+       #    google, goto, mirrorlist, remove, rename, repolist, search,
+       #    theme, websetup, wmd)
+       ######################################################################
+
+       # attachment plugin
+       # enhanced PageSpec specifying what attachments are allowed
+       #allowed_attachments => 'virusfree() and mimetype(image/*) and maxsize(50kb)',
+       # virus checker program (reads STDIN, returns nonzero if virus found)
+       #virus_checker => 'clamdscan -',
+
+       # comments plugin
+       # PageSpec of pages where comments are allowed
+       #comments_pagespec => 'blog/* and !*/Discussion',
+       # PageSpec of pages where posting new comments is not allowed
+       #comments_closed_pagespec => 'blog/controversial or blog/flamewar',
+       # Base name for comments, e.g. "comment_" for pages like "sandbox/comment_12"
+       #comments_pagename => '',
+       # Interpret directives in comments?
+       #comments_allowdirectives => 0,
+       # Allow anonymous commenters to set an author name?
+       #comments_allowauthor => 0,
+       # commit comments to the VCS
+       #comments_commit => 1,
+
+       # getsource plugin
+       # Mime type for returned source.
+       #getsource_mimetype => 'text/plain; charset=utf-8',
+
+       # mirrorlist plugin
+       # list of mirrors
+       #mirrorlist => {},
+
+       # repolist plugin
+       # URIs of repositories containing the wiki's source
+       #repositories => [qw{svn://svn.example.org/wiki/trunk}],
+
+       # search plugin
+       # path to the omega cgi program
+       #omega_cgi => '/usr/lib/cgi-bin/omega/omega',
+
+       # theme plugin
+       # name of theme to enable
+       #theme => 'actiontabs',
+
+       # websetup plugin
+       # list of plugins that cannot be enabled/disabled via the web interface
+       #websetup_force_plugins => [],
+       # list of additional setup field keys to treat as unsafe
+       #websetup_unsafe => [],
+       # show unsafe settings, read-only, in web interface?
+       #websetup_show_unsafe => 1,
+
+       ######################################################################
+       # widget plugins
+       #   (calendar, color, conditional, cutpaste, date, format, fortune,
+       #    graphviz, haiku, img, linkmap, listdirectives, map, more,
+       #    orphans, pagecount, pagestats, poll, polygen, postsparkline,
+       #    progress, shortcut, sparkline, table, template, teximg, toc,
+       #    toggle, version)
+       ######################################################################
+
+       # calendar plugin
+       # base of the archives hierarchy
+       #archivebase => 'archives',
+       # PageSpec of pages to include in the archives; used by ikiwiki-calendar command
+       #archive_pagespec => 'page(posts/*) and !*/Discussion',
+
+       # listdirectives plugin
+       # directory in srcdir that contains directive descriptions
+       #directive_description_dir => 'ikiwiki/directive',
+
+       # teximg plugin
+       # Should teximg use dvipng to render, or dvips and convert?
+       #teximg_dvipng => '',
+       # LaTeX prefix for teximg plugin
+       #teximg_prefix => '\\documentclass{article}
+       #\\usepackage{amsmath}
+       #\\usepackage{amsfonts}
+       #\\usepackage{amssymb}
+       #\\pagestyle{empty}
+       #\\begin{document}
+       #',
+       # LaTeX postfix for teximg plugin
+       #teximg_postfix => '\\end{document}',
+
+       ######################################################################
+       # other plugins
+       #   (aggregate, autoindex, brokenlinks, camelcase, ddate, embed,
+       #    favicon, goodstuff, htmlbalance, localstyle, pagetemplate,
+       #    pingee, pinger, prettydate, recentchanges, recentchangesdiff,
+       #    relativedate, rsync, sidebar, smiley, sortnaturally, tag,
+       #    testpagespec, underlay)
+       ######################################################################
+
+       # aggregate plugin
+       # enable aggregation to internal pages?
+       #aggregateinternal => 1,
+       # allow aggregation to be triggered via the web?
+       #aggregate_webtrigger => 0,
+
+       # camelcase plugin
+       # list of words to not turn into links
+       #camelcase_ignore => [],
+
+       # pinger plugin
+       # how many seconds to try pinging before timing out
+       #pinger_timeout => 15,
+
+       # prettydate plugin
+       # format to use to display date
+       #prettydateformat => '%X, %B %o, %Y',
+
+       # recentchanges plugin
+       # name of the recentchanges page
+       recentchangespage => 'recentchanges',
+       # number of changes to track
+       recentchangesnum => 100,
+
+       # rsync plugin
+       # command to run to sync updated pages
+       #rsync_command => 'rsync -qa --delete . user@host:/path/to/docroot/',
+
+       # sidebar plugin
+       # show sidebar page on all pages?
+       #global_sidebars => 1,
+
+       # tag plugin
+       # parent page tags are located under
+       #tagbase => 'tag',
+       # autocreate new tag pages?
+       #tag_autocreate => 1,
+
+       # underlay plugin
+       # extra underlay directories to add
+       #add_underlays => [qw{/home/hartmans/wiki.underlay}],
+}