Index: libabac/abac_xml.c
===================================================================
--- libabac/abac_xml.c	(revision e50f807d08d2317f946f7886c04a062102b5e485)
+++ libabac/abac_xml.c	(revision a2b9fd231c3906b8b529be44156ecfad323b089d)
@@ -65,5 +65,8 @@
 #define VERSIONLEN 256
 
-/* XML template for a new RT0 credential.  Fill in the RT0 to store (XML
+/* These templates are given in defines so that they can initialize the
+ * specialization structures. */
+
+/* XML template for a new RT0 v1.0 credential.  Fill in the RT0 to store (XML
  * escaped) and the expiration time (formated using strftime_format and
  * strftime). */
@@ -101,5 +104,5 @@
 "</signed-credential>"
 
-/* XML template for a new RT0 credential.  Fill in the RT0 to store (XML
+/* XML template for a new RT0 v1.1 credential.  Fill in the RT0 to store (XML
  * escaped) and the expiration time (formated using strftime_format and
  * strftime). */
@@ -143,4 +146,6 @@
 "</signed-credential>"
 
+/* Forward declarations of functions to parse and generate rt0 elements in
+ * various formats */
 xmlChar *encode_rt0_xml_v10(abac_attribute_t *);
 xmlChar *encode_rt0_xml_v11(abac_attribute_t *);
@@ -148,11 +153,17 @@
 xmlChar **parse_rt0_xml_v11(xmlNodePtr);
 
+/* Structure that specializes XML parsing */
 typedef struct {
-    char *version;
+    /* Version to use these functions for */
+    char *version;  
+    /* Convert an ABAC attribute into an rt0 element */
     xmlChar *(*rt0_to_xml)(abac_attribute_t *);
+    /* Convert an rt0 element into a list of RT0 strings */
     xmlChar **(*xml_to_rt0)(xmlNodePtr);
+    /* The overall template to generate this version of credential */
     char *out_template;
 } GENI_xml_processing_t;
 
+/* The processing specializations */
 GENI_xml_processing_t xml_proc[] = {
     { "1.0", encode_rt0_xml_v10, parse_rt0_xml_v10, template_v10},
@@ -161,4 +172,5 @@
 };
 
+/* Query funtion to convert a processing version into the functions above */
 GENI_xml_processing_t *get_xml_processing(char *ver) {
     int i ;
@@ -697,31 +709,4 @@
 }
 
-/* Compare the version string (major.minor) to the major and minor numbers, and
- * return true if the version string is >= the major minor pair. */
-static int check_GENI_abac_version(xmlChar *version, int major, int minor) {
-    xmlChar lversion[VERSIONLEN];   /* Buffer to parse version in */
-    xmlChar *lp = &lversion[0];	    /* strsep needs a pointer it can modify */
-    int maj = 0;		    /* Parsed major number */
-    int min = 0;		    /* Parsed minor number */
-    char *values[2];
-    int ret=2;
-
-    snprintf((char *) lp, VERSIONLEN, "%s", (char *) version);
-    abac_split(lp, ".", values, &ret);
-    if(ret==2) {
-        /* split successful, values[0] is the major number,
-           values[1] is the minor, now we parse integers*/
-        if ( *values[0] == '\0') return 0;
-        maj = strtol(values[0], NULL, 10);
-        if ( *values[1] == '\0') return 0;                            
-        min = strtol(values[1], NULL, 10);    
-    } else return 0;                                                  
-                                                                      
-    if (maj > major ||              
-           (maj == major && min > minor) ||                           
-               (maj == major && min == minor) ) return 1;             
-    else return 0;                                                    
-}  
-
 /*
  * If n has a child that is an element named name, return a pointer to it,
@@ -742,4 +727,9 @@
 }
 
+/*
+ * Convert a version 1.0 rt0 section to an RT0 string, returned in an array of
+ * strings.  This is just allocating the array and copying the string.  RT0 1.0
+ * has no structure.
+ */
 xmlChar **parse_rt0_xml_v10(xmlNodePtr n) {
     xmlChar *txt;
@@ -759,4 +749,5 @@
 }
 
+/* Return the length of the string pointed to by rn, ignoring whitespace */
 static int role_len(xmlChar *rn) {
     xmlChar *p;
@@ -768,4 +759,16 @@
 }
 
+/* Return the length of the RT0 string represented bt the RT0 1.1 term.  That
+ * term looks like:
+ * <head>
+ *  <ABACprincipal><keyid>...</keyid><mnemonic>...</menmonic></ABACprincipal>
+ *  <role>...</role>
+ *  <linking_role>...</linking_role>
+ * </head>
+ * The container can be either a head or a tail, and the role and linking_role
+ * are optional.  The result is the number of non whitespace characters in the
+ * keyid, role, and linking_role fields (if present) plus a dot to separate
+ * each field.
+ */
 static int term_len(xmlNodePtr n) {
     int len = 0;
@@ -788,5 +791,8 @@
 }
 
-
+/* Copy non-whitespace characters from rn to dest.  Return the final vaue of
+ * dest, but no guarantees are made about it.  The caller must make sure there
+ * is enough space in dest.
+ */
 static xmlChar *role_copy(xmlChar *rn, xmlChar *dest) {
     while (*rn) {
@@ -797,4 +803,13 @@
 }
 
+/* Turn the contents of the node pointer into a dotted string representation of
+ * the RT0 term.  For example
+ * <tail>
+ *  <ABACprincipal><keyid>P</keyid><mnemonic>...</menmonic></ABACprincipal>
+ *  <role>r2</role>
+ *  <linking_role>r1</linking_role>
+ * </tail>
+ * becomes P.r1.r2.
+ */
 static xmlChar *term_copy(xmlNodePtr n, xmlChar *dest) {
     xmlNodePtr p = get_direct_child(n, "ABACprincipal");
@@ -814,4 +829,8 @@
 }
 
+/*
+ * Append at most sz characters from a to d and advance d by sz characters.  No
+ * checking is done.
+ */
 static xmlChar *append_and_move(xmlChar *d, xmlChar *a, int sz) {
     strncat((char *) d, (char *) a, sz);
@@ -819,4 +838,22 @@
 }
 
+/*
+ * Parse a structured RT0 v 1.1 xml into an RT0 string.  For example
+ * <head>
+ *  <ABACprincipal><keyid>A</keyid><mnemonic>...</menmonic></ABACprincipal>
+ *  <role>r</role>
+ * </head>
+ * <tail>
+ *  <ABACprincipal><keyid>B</keyid><mnemonic>...</menmonic></ABACprincipal>
+ *  <role>r2</role>
+ *  <linking_role>r1</linking_role>
+ * </tail>
+ * <tail>
+ *  <ABACprincipal><keyid>C</keyid><mnemonic>...</menmonic></ABACprincipal>
+ *  <role>r2</role>
+ * </tail>
+ *
+ * Converts to A.r<-B.r1.r2 & C.r2
+ */
 xmlChar **parse_rt0_xml_v11(xmlNodePtr n) {
     int len = 3;    /* Length of the RT0 string we're building initially 3 for
@@ -828,4 +865,7 @@
     xmlChar *d = NULL;
 
+    /* Compute the length of the new string and make sure we have a head and at
+     * least one tail.
+     */
     if ( !n ) return NULL;
 
@@ -843,4 +883,6 @@
     }
     if ( heads != 1 || tails < 1) return NULL;
+
+    /* Allocate the return value */
     if ( !(rv = malloc(2 * sizeof(xmlChar *)))) return NULL;
     if (!(rv[0] = malloc(len)) ) {
@@ -848,4 +890,6 @@
 	return NULL;
     }
+
+    /* Translate term by term */
     d = rv[0];
     if ( !( c = get_direct_child(n, "head"))) goto fail;
@@ -872,7 +916,11 @@
 /*
  * Parse an ABAC credential (that has had its signature checked.  Make sure it
- * has not expired and that its version is at least 1.0 (XXX: parameterize
- * that), and return the RT0 it encodes as the only entry in an NULL-terminated
- * array of strings (just like parse_privilege). On failure return NULL. */
+ * has not expired and that its version is one we know.  Return the RT0 it
+ * encodes as the only entry in an NULL-terminated array of strings (just like
+ * parse_privilege). On failure return NULL.  In addition to parsing the
+ * certificate, we add the issuer's identity from the signature to the
+ * controlling context, if any.  ctxt_id_certs is the list of certificates to
+ * which the new certificate is added.
+ */
 xmlChar **parse_abac(xmlDocPtr doc, void *ctxt_id_certs) {
     xmlNodePtr root = NULL;	/* XML root node */
@@ -885,4 +933,5 @@
     xmlChar *txt;		/* rt0 content */
     xmlChar **rv = NULL;	/* return value */
+    xmlChar *issuer_ptr=NULL;	/* Issuer certificate to add to ctxt_id_certs */
     GENI_xml_processing_t *proc = NULL; /* Specialization for version number */
     int ncred = 0;		/* number of creds in rv */
@@ -924,6 +973,8 @@
 
     /* extract issuer pem and insert */
-    xmlChar *issuer_ptr=get_issuer(doc);
-    if(issuer_ptr && abac_verifier_load_id_chars(ctxt_id_certs,issuer_ptr) != 0 /*ABAC_CERT_SUCCESS*/) {
+    issuer_ptr=get_issuer(doc);
+    if( issuer_ptr && 
+	    abac_verifier_load_id_chars(ctxt_id_certs,issuer_ptr) != 
+	    ABAC_CERT_SUCCESS) {
         goto fail;
     }
@@ -942,5 +993,8 @@
  * NULL-terminated array of strings.  If the signature or parsing fails, return
  * NULL. Demultiplexed to parse_privilege or parse_abac to do the parsing and
- * uses check_signature to confirm the sig. */
+ * uses check_signature to confirm the sig. If ctxt_id_certs is a list of
+ * identities known to a context.  If it is not NULL and identity certs appear
+ * (as they do in GENI credentials) add them to that list, which adds them to
+ * the ABAC context. */
 char **read_credential(void *ctxt_id_certs, char *infile, 
 	char **in_xml) {
@@ -983,11 +1037,5 @@
 
 
-/* from Ted's writer */
-
-/* maximum rt0 stringlen */
-#define CREDLEN 1024
-/* Maximum version len */
-#define VERSIONLEN 256
-
+/* format for dates in <expires> */
 char *strftime_fmt = "%FT%TZ";
 #define EXPIRESLEN 20
@@ -1052,4 +1100,6 @@
 }
 
+/* Template to create a head element in structured XML for RT0 (v1.1).  All
+ * heads are a single role element */
 static char *head_template = 
 "<head>\n"
@@ -1058,4 +1108,6 @@
 "</head>\n";
 
+/* Templates to create a tail in structured XML  based on how many of
+ * principal, role, and linking role are present. */
 static char *tail_template[] = {
 "<tail>\n"
@@ -1073,19 +1125,29 @@
 };
 
+/* Convert the given attribute to the RT0 structured XML representation used by
+ * version 1.1 credentials.
+ */
 xmlChar *encode_rt0_xml_v11(abac_attribute_t *a) {
-    int htlen = strlen(head_template);
-    int ttlen = strlen(tail_template[2]);
+    int htlen = strlen(head_template);	    /* head template length */
+    int ttlen = strlen(tail_template[2]);   /* length of the longest tail
+					       template */
+    /* Size of the string we'll need - start with a head template and string */
     int sz = strlen(abac_attribute_get_head(a)) + htlen;
+    /* Number of tails in the sttribute */
     int ntails = abac_attribute_get_ntails(a);
-    char *princ_role[2];
-    char *copy = abac_xstrdup(abac_attribute_get_head(a));
-    int npr = 2;
-    char *tmp = NULL;
-    char *rv = NULL;
-    int i;
-
+    char *princ_role[2];    /* Used to split the head role */
+    char *copy = abac_xstrdup(abac_attribute_get_head(a)); /* splitting */
+    int npr = 2;	    /* Number of parts in the head role */
+    char *tmp = NULL;	    /* A temporary to build each tail element */
+    char *rv = NULL;	    /* The return value */
+    int i;		    /* Scratch */
+
+    /* Add the tail lengths to the total length (assume all tails will need the
+     * largest template for slop). */
     for ( i = 0 ; i < ntails; i++)
 	sz += strlen(abac_attribute_get_tail_n(a, i)) + ttlen;
 
+    /* Get the rv and scratch string.  Since tmp is as long as the whole
+     * string, it's big enough for any substring */
     if ( !(rv = (char *) xmlMalloc(sz)) ) goto fail;
     if ( !(tmp = (char *) xmlMalloc(sz)) ) goto fail;
@@ -1095,7 +1157,10 @@
 	goto fail;
 
+    /* Put the head in */
     sz -= snprintf(rv, sz, head_template, princ_role[0], princ_role[1]);
 
     for ( i = 0 ; i < ntails; i++) {
+	/* Make a role for each tail and use those functions to write out the
+	 * structures for the different kinds of role. */
 	abac_role_t *r = abac_role_from_string(abac_attribute_get_tail_n(a,i));
 	int ts;
