Index: libabac/abac_graph.c
===================================================================
--- libabac/abac_graph.c	(revision 53e540d5b3ba8b09dcdf1f90cf514182a491d9d3)
+++ 	(revision )
@@ -1,540 +1,0 @@
-#include <assert.h>
-#include <stdlib.h>
-
-#include "abac_graph.h"
-
-#include "abac_set.h"
-#include "abac_util.h"
-
-#include "uthash.h"
-
-// vertex
-struct _abac_vertex_t {
-    abac_role_t *role;
-    char *name;
-
-    abac_list_t *edges;
-
-    // only relevant to intersection edges
-    abac_list_t *prereqs;
-
-    UT_hash_handle hh;
-};
-
-// edge
-typedef struct _abac_edge_t {
-    abac_vertex_t *vertex;
-    abac_credential_t *credential;
-} abac_edge_t;
-
-// derived edge
-typedef struct _abac_derived_key_t {
-    abac_vertex_t *head;
-    abac_edge_t *tail;
-} abac_derived_key_t;
-
-typedef struct _abac_derived_t {
-    abac_derived_key_t key;
-    UT_hash_handle hh;
-} abac_derived_t;
-
-// graph
-struct _abac_graph_t {
-    abac_vertex_t *vertices;
-    abac_derived_t *derived;
-    int dirty;
-};
-
-// ugghhhghhhghh need this for intersections
-abac_list_t *abac_role_prereqs(abac_role_t *);
-
-/**
- * Create a new graph.
- */
-abac_graph_t *abac_graph_new(void) {
-    abac_graph_t *graph = abac_xmalloc(sizeof(abac_graph_t));
-
-    graph->vertices = NULL;
-    graph->derived = NULL;
-    graph->dirty = 0;
-
-    return graph;
-}
-
-/**
- * Deep copy a graph.
- */
-abac_graph_t *abac_graph_dup(abac_graph_t *graph) {
-    abac_vertex_t *vertex;
-    abac_edge_t *edge;
-
-    abac_graph_t *clone = abac_graph_new();
-
-    // copy the vertices edge by edge
-    for (vertex = graph->vertices; vertex != NULL; vertex = vertex->hh.next)
-        abac_list_foreach(vertex->edges, edge,
-            // only copy non-derived edges
-            if (edge->credential != NULL)
-                abac_graph_add_credential(clone, edge->credential);
-        );
-
-    return clone;
-}
-
-/**
- * Add a vertex to the graph. Should only be called by abac_graph_add_credential.
- */
-static abac_vertex_t *_get_vertex(abac_graph_t *graph, abac_role_t *role) {
-    abac_vertex_t *vertex;
-    char *string;
-    
-    string = abac_role_string(role);
-    HASH_FIND_STR(graph->vertices, string, vertex);
-
-    // add the vertex if it doesn't exist
-    if (vertex == NULL) {
-        vertex = abac_xmalloc(sizeof(abac_vertex_t));
-        vertex->role = abac_role_dup(role);
-        vertex->name = abac_role_string(vertex->role);
-
-        // create the list of edges
-        vertex->edges = abac_list_new();
-
-        // for intersections, always NULL on normal vertices
-        if (abac_role_is_intersection(role)) {
-            abac_role_t *prereq;
-            vertex->prereqs = abac_list_new();
-
-            // add each prereq to the vertex
-            abac_list_foreach(abac_role_prereqs(role), prereq,
-                abac_vertex_t *tail_vertex = _get_vertex(graph, prereq);
-                abac_list_add(vertex->prereqs, tail_vertex);
-            );
-        }
-
-        // normal edges have no prereqs
-        else
-            vertex->prereqs = NULL;
-
-        // add it to the vertices
-        HASH_ADD_KEYPTR(hh, graph->vertices, vertex->name, strlen(vertex->name), vertex);
-    }
-
-    return vertex;
-}
-
-/**
- * Add a credential to the credential graph.
- */
-int abac_graph_add_credential(abac_graph_t *graph, abac_credential_t *cred) {
-    abac_vertex_t *head_vertex, *tail_vertex;
-    abac_edge_t *edge;
-
-    assert(cred != NULL);
-
-    abac_role_t *head = abac_credential_head(cred);
-    abac_role_t *tail = abac_credential_tail(cred);
-
-    // a valid credential must have a role for the head
-    if (!abac_role_is_role(head)) return 0;
-
-    head_vertex = _get_vertex(graph, head);
-    tail_vertex = _get_vertex(graph, tail);
-
-    // make sure we don't insert the same edge twice (ugh)
-    abac_list_foreach(head_vertex->edges, edge,
-        if (edge->vertex == tail_vertex)
-            return 0;
-    );
-
-    // create the edge and add it
-    edge = abac_xmalloc(sizeof(abac_edge_t));
-    edge->vertex = tail_vertex;
-    edge->credential = abac_credential_dup(cred);
-
-    abac_list_add(head_vertex->edges, edge);
-
-    // must re-derive edges
-    graph->dirty = 1;
-
-    return 1;
-}
-
-// find the principals that have a role
-static abac_set_t *_find_principals(abac_graph_t *graph, abac_vertex_t *start_vertex) {
-    abac_set_t *principals = abac_set_new();
-
-    abac_list_t *traversal = abac_graph_postorder(graph, start_vertex->role);
-    abac_vertex_t *vertex;
-
-    abac_list_foreach(traversal, vertex,
-        if (abac_role_is_principal(vertex->role))
-            abac_set_add(principals, abac_role_string(vertex->role));
-    );
-
-    abac_list_free(traversal);
-    return principals;
-}
-
-// remove any derived edges from the graph
-void _clear_derived(abac_graph_t *graph) {
-    abac_derived_t *current;
-
-    while (graph->derived) {
-        current = graph->derived;
-
-        HASH_DEL(graph->derived, current);
-
-        abac_vertex_t *head = current->key.head;
-        abac_edge_t *tail = current->key.tail;
-        assert(tail->credential == NULL);
-
-        // this can fail, but we assume the data structures are consistent
-        abac_list_remove(head->edges, tail);
-
-        free(current);
-        free(tail);
-    }
-}
-
-// add a derived edge, returns 1 if added 0 if dup
-static int _derived_edge(abac_graph_t *graph, abac_vertex_t *head, abac_vertex_t *tail) {
-    abac_edge_t *edge;
-
-    // don't add duplicate edges
-    abac_list_foreach(head->edges, edge,
-        if (edge->vertex == tail)
-            return 0;
-    );
-
-    debug_printf("derived edge %s <- %s\n", head->name, tail->name);
-
-    edge = abac_xmalloc(sizeof(abac_edge_t));
-    edge->vertex = tail;
-    edge->credential = NULL;
-    abac_list_add(head->edges, edge);
-
-    // add to list of derived edges
-    abac_derived_t *derived = abac_xmalloc(sizeof(abac_derived_t));
-    derived->key.head = head;
-    derived->key.tail = edge;
-    HASH_ADD(hh, graph->derived, key, sizeof(abac_derived_key_t), derived);
-
-    return 1;
-}
-
-// find a vertex by name
-abac_vertex_t *_find_vertex(abac_graph_t *graph, char *name) {
-    abac_vertex_t *ret = NULL;
-    HASH_FIND_STR(graph->vertices, name, ret);
-    return ret;
-}
-
-/**
- * Single iteration of deriving new edges. Returns the number of new edges
- * added.
- */
-static int _derive_links_iter(abac_graph_t *graph) {
-    int count = 0;
-    abac_vertex_t *vertex;
-
-    for (vertex = graph->vertices; vertex != NULL; vertex = vertex->hh.next) {
-        // intersection
-        if (abac_role_is_intersection(vertex->role)) {
-            // for each prereq edge:
-            //     find principals that have the edge
-            // find intersection of all sets
-            // for each principal B in intersection:
-            //     add link
-
-            char *name;
-            abac_vertex_t *prereq;
-            abac_set_t *principals = NULL;
-
-            abac_list_foreach(vertex->prereqs, prereq,
-                abac_set_t *cur = _find_principals(graph, prereq);
-
-                if (principals == NULL)
-                    principals = cur;
-                else {
-                    abac_set_intersect(principals, cur);
-                    abac_set_free(cur);
-                }
-
-                if (abac_set_size(principals) == 0)
-                    goto isect_done;
-            );
-
-            abac_list_t *prin_names = abac_set_elements(principals);
-            abac_list_foreach(prin_names, name,
-                abac_vertex_t *principal = _find_vertex(graph, name);
-                count += _derived_edge(graph, vertex, principal);
-            );
-
-            abac_list_free(prin_names);
-isect_done:
-            abac_set_free(principals);
-        }
-
-        // linking role
-        else if (abac_role_is_linking(vertex->role)) {
-            // linking roles take the form A.r1.r2
-            char *A_r1 = abac_role_linked_role(vertex->role);
-            char *r2 = abac_role_role_name(vertex->role);
-
-            // find the linked role in the graph
-            abac_vertex_t *A_r1_vertex;
-            HASH_FIND_STR(graph->vertices, A_r1, A_r1_vertex);
-            if (A_r1_vertex == NULL)
-                continue;
-
-            // find the principals that have A.r1
-            abac_set_t *principals = _find_principals(graph, A_r1_vertex);
-            char *B;
-
-            abac_list_t *elts = abac_set_elements(principals);
-
-            // and add a link for each B.r2 to A.r1.r2
-            abac_list_foreach(elts, B,
-                int B_len = strlen(B);
-                int r2_len = strlen(r2);
-
-                // create the string B.r2, thx C
-                char *B_r2 = malloc(B_len + r2_len + 2);
-                memcpy(B_r2, B, B_len);
-                B_r2[B_len] = '.';
-                memcpy(B_r2 + B_len + 1, r2, r2_len);
-                B_r2[B_len + r2_len + 1] = 0;
-
-                // add an edge if the principal's granted it to someone
-                abac_vertex_t *B_r2_vertex = _find_vertex(graph, B_r2);
-                if (B_r2_vertex) {
-                    debug_printf("adding edge from %s to %s\n", B_r2, abac_role_string(vertex->role));
-                    count += _derived_edge(graph, vertex, B_r2_vertex);
-                }
-
-#ifdef DEBUG
-                debug_printf("    incoming edges for %s\n", abac_role_string(vertex->role));
-                abac_edge_t *cur;
-                abac_list_foreach(vertex->edges, cur,
-                    debug_printf("        %s (%s)\n", abac_role_string(cur->vertex->role), cur->vertex->name);
-                );
-#endif
-
-                free(B_r2);
-            );
-
-            abac_list_free(elts);
-            abac_set_free(principals);
-        }
-    }
-
-    return count;
-}
-
-/**
- * Derive all implied edges in the graph. These can come from linking roles
- * and intersections.
- *
- * We have to do it iteratively because derived edges can imply new edges.
- */
-void abac_graph_derive_links(abac_graph_t *graph) {
-    if (!graph->dirty)
-        return;
-
-    // iterate as long as new links are derived
-    while (_derive_links_iter(graph) > 0)
-        ;
-
-    graph->dirty = 0;
-}
-
-static void _order_recurse(abac_vertex_t *vertex, abac_set_t *seen, int preorder, abac_list_t *stack) {
-    abac_edge_t *incoming;
-
-    // don't revisit nodes
-    if (!abac_set_add(seen, abac_role_string(vertex->role)))
-        return;
-
-    if (preorder)
-        abac_list_add(stack, vertex);
-
-    // recurse along the incoming vertices
-    abac_list_foreach(vertex->edges, incoming,
-        _order_recurse(incoming->vertex, seen, preorder, stack);
-    );
-
-    if (!preorder)
-        abac_list_add(stack, vertex);
-}
-
-static abac_list_t *_order(abac_graph_t *graph, abac_role_t *start, int preorder) {
-    debug_printf("%sorder at %s\n", preorder ? "pre" : "post", abac_role_string(start));
-
-    abac_vertex_t *start_vertex = _get_vertex(graph, start);
-    abac_set_t *seen = abac_set_new();
-
-    // create the return list
-    abac_list_t *stack = abac_list_new();
-
-    _order_recurse(start_vertex, seen, preorder, stack);
-
-    abac_set_free(seen);
-
-    return stack;
-}
-
-abac_list_t *abac_graph_postorder(abac_graph_t *graph, abac_role_t *start) {
-    return _order(graph, start, 0);
-}
-
-/**
- * Postorder traverse the graph and return all the credentials within.
- */
-abac_list_t *abac_graph_postorder_credentials(abac_graph_t *graph, char *start) {
-    abac_vertex_t *vertex;
-    abac_edge_t *incoming;
-
-    // get the postorder of vertices
-    abac_role_t *role = abac_role_from_string(start);
-    abac_list_t *order = abac_graph_postorder(graph, role);
-
-    // go through the list and dup all the credentials
-    abac_list_t *credentials = abac_list_new();
-    abac_list_foreach(order, vertex,
-        abac_list_foreach(vertex->edges, incoming,
-            if (incoming->credential != NULL)
-                abac_list_add(credentials, abac_credential_dup(incoming->credential));
-        );
-    );
-
-    abac_role_free(role);
-    abac_list_free(order);
-
-    return credentials;
-}
-
-static void _query(abac_graph_t *graph, char *role_name, char *principal, abac_graph_t *return_graph) {
-    abac_vertex_t *vertex;
-    abac_edge_t *incoming;
-
-    abac_role_t *role = abac_role_from_string(role_name);
-    abac_role_t *prin_role = abac_role_from_string(principal);
-
-    // give up on bogus roles
-    if (role == NULL || prin_role == NULL) {
-        free(role);
-        free(prin_role);
-        return;
-    }
-
-    printf("\nQQQ ===> graph query with prin_role(%s) on role(%s)\n", abac_role_string(prin_role), abac_role_string(role));
-
-    abac_set_t *on_path = abac_set_new();
-    abac_set_add(on_path, abac_role_string(prin_role));
-
-    abac_list_t *traversal = abac_graph_postorder(graph, role);
-    abac_list_foreach(traversal, vertex,
-        abac_role_t *role = vertex->role;
-        printf("\nQQQ ===> with role %s\n", abac_role_string(role));
-
-        abac_list_foreach(vertex->edges, incoming,
-            abac_role_t *incoming_role = incoming->vertex->role;
-            printf("\nQQQ ===> incoming role %s\n", abac_role_string(incoming_role));
-
-            if (!abac_set_contains(on_path, abac_role_string(incoming_role)))
-                continue;
-
-            abac_set_add(on_path, abac_role_string(role));
-
-            // get implying edges for intersection vertices
-            if (abac_role_is_intersection(role)) {
-                abac_vertex_t *prereq;
-                abac_list_foreach(vertex->prereqs, prereq,
-                    printf("QQQ - prereq->name is %s\n", prereq->name); 
-                    _query(graph, prereq->name, principal, return_graph);
-                );
-            }
-
-            // recursively find linked roles
-            else if (abac_role_is_linking(role)) {
-                char *linked_role = abac_role_linked_role(role);
-                char *principal = abac_role_principal(incoming_role);
-
-                printf("QQQ - recursive linked %s\n", linked_role);
-                _query(graph, linked_role, principal, return_graph);
-            }
-
-            // add non-derived edges to the proof graph
-            else
-                abac_graph_add_credential(return_graph, incoming->credential);
-        );
-    );
-
-    abac_list_free(traversal);
-    abac_set_free(on_path);
-    abac_role_free(role);
-    abac_role_free(prin_role);
-}
-
-abac_graph_t *abac_graph_query(abac_graph_t *graph, char *role, char *principal) {
-    abac_graph_derive_links(graph);
-
-    abac_graph_t *return_graph = abac_graph_new();
-    _query(graph, role, principal, return_graph);
-    abac_graph_derive_links(return_graph);
-    return return_graph;
-}
-
-/**
- * Get all the credentials (attribute/issuer cert pairs) from the graph.
- */
-abac_list_t *abac_graph_credentials(abac_graph_t *graph) {
-    abac_list_t *credentials = abac_list_new();
-
-    abac_vertex_t *vertex;
-
-    for (vertex = graph->vertices; vertex != NULL; vertex = vertex->hh.next) {
-        abac_edge_t *edge;
-        abac_list_foreach(vertex->edges, edge,
-            if (edge->credential != NULL)
-                abac_list_add(credentials, abac_credential_dup(edge->credential));
-        );
-    }
-
-    return credentials;
-}
-
-void abac_graph_free(abac_graph_t *graph) {
-    abac_vertex_t *vertex;
-    abac_edge_t *edge;
-
-    // kill derived edges
-    _clear_derived(graph);
-
-    // delete vertices
-    while ((vertex = graph->vertices) != NULL) {
-        HASH_DEL(graph->vertices, vertex);
-
-        abac_role_free(vertex->role);
-
-        abac_list_foreach(vertex->edges, edge,
-            if (edge->credential != NULL)
-                abac_credential_free(edge->credential);
-            free(edge);
-        );
-        abac_list_free(vertex->edges);
-
-        // the prereq vertices will be freed by the outer while loop
-        if (vertex->prereqs != NULL)
-            abac_list_free(vertex->prereqs);
-
-        free(vertex);
-    }
-
-    free(graph);
-}
-
-abac_role_t *abac_vertex_role(abac_vertex_t *vertex) {
-    return vertex->role;
-}
Index: libabac/abac_graph.h
===================================================================
--- libabac/abac_graph.h	(revision 53e540d5b3ba8b09dcdf1f90cf514182a491d9d3)
+++ 	(revision )
@@ -1,29 +1,0 @@
-#ifndef __GRAPH_H__
-#define __GRAPH_H__
-
-#include "abac.h"
-#include "abac_list.h"
-#include "abac_verifier.h"
-
-#define ABAC_GRAPH_CRED_OK          0   // adding a credential succeeded
-#define ABAC_GRAPH_CRED_INVALID     -1  // the credential was invalid
-#define ABAC_GRAPH_CRED_DUP         -2  // the credential is already present in the graph
-
-typedef struct _abac_graph_t abac_graph_t;
-typedef struct _abac_vertex_t abac_vertex_t;
-
-abac_graph_t *abac_graph_new(void);
-abac_graph_t *abac_graph_dup(abac_graph_t *graph);
-
-// returns a status as defined at the top of the file
-int abac_graph_add_credential(abac_graph_t *graph, abac_credential_t *cred);
-void abac_graph_derive_links(abac_graph_t *graph);
-abac_list_t *abac_graph_postorder(abac_graph_t *graph, abac_role_t *start);
-abac_list_t *abac_graph_postorder_credentials(abac_graph_t *graph, char *start);
-abac_graph_t *abac_graph_query(abac_graph_t *graph, char *role, char *principal);
-abac_list_t *abac_graph_credentials(abac_graph_t *graph);
-void abac_graph_free(abac_graph_t *graph);
-
-abac_role_t *abac_vertex_role(abac_vertex_t *vertex);
-
-#endif /* __GRAPH_H__ */
Index: libabac/abac_param.c
===================================================================
--- libabac/abac_param.c	(revision 718ad9243faff3a00dea5c5c5b2ef6fe89caedbe)
+++ libabac/abac_param.c	(revision 718ad9243faff3a00dea5c5c5b2ef6fe89caedbe)
@@ -0,0 +1,207 @@
+
+/***********************************************************
+   abac_param.c
+***********************************************************/
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "abac_list.h"
+#include "abac_util.h"
+
+#include "abac_pl.h"
+
+struct _abac_condition_t {
+    char *string;
+};
+
+struct _abac_param_t {
+    int type;
+    char *name;
+    abac_condition_t *constraint;
+}; 
+
+/* new, free, add one */
+struct _abac_param_list_t {
+    abac_list_t *list;
+};
+
+/******************************************************************/
+
+static abac_condition_t *abac_condition_new(char *condition)
+{
+     abac_condition_t *ptr=abac_xmalloc(sizeof(abac_condition_t));
+     ptr->string=condition;
+     return ptr;
+}
+
+static void abac_condition_free(abac_condition_t *ptr)
+{
+     free(ptr->string);
+     free(ptr);
+}
+
+abac_param_t *abac_param_new(int type, char *name, char *cond)
+{
+     abac_condition_t *constraint=NULL;
+     if (cond) {
+         constraint=abac_condition_new(cond);
+     }
+     abac_param_t *ptr=abac_xmalloc(sizeof(abac_param_t));
+     ptr->type=type;
+     ptr->name=name;
+     ptr->constraint=constraint;
+     return ptr;
+}
+
+void abac_param_free(abac_param_t *ptr)
+{
+    if(ptr->constraint) {
+         abac_condition_free(ptr->constraint);
+    }
+    free(ptr->name);
+    free(ptr);
+}
+
+abac_param_list_t *abac_param_list_new(abac_param_t *param)
+{
+    abac_param_list_t *ptr=abac_xmalloc(sizeof(abac_param_list_t));
+    ptr->list=abac_list_new();
+    abac_list_add(ptr->list, param);
+    return ptr;
+}
+
+abac_param_list_t *abac_param_list_free(abac_param_list_t *ptr)
+{
+    abac_list_t *list=ptr->list;
+    abac_param_t  *cur;
+    abac_list_foreach(list, cur,
+           abac_param_free(cur);
+    );
+    abac_list_free(list);
+    free(ptr);
+}
+
+abac_param_list_t *abac_param_list_add_param(abac_param_list_t *ptr, abac_param_t *param)
+{
+    abac_list_t *list=ptr->list;
+    abac_list_add(list, param);
+    return ptr;
+}
+
+abac_param_t *abac_param_add_constraint(abac_param_t *ptr, abac_condition_t *cond)
+{
+    if(ptr->constraint) {
+        abac_condition_free(ptr->constraint);
+    }
+    ptr->constraint = cond;
+    return ptr;
+}
+
+/* name or name:cond */
+static char *abac_param_string_with_condition(abac_param_t *ptr)
+{
+    char *tmp=NULL;
+    char *cond=NULL;
+    char *name=ptr->name;
+    int len=strlen(name);
+    if(ptr->constraint) {
+       cond=ptr->constraint->string;
+       len=len+strlen(cond)+1;
+    }
+    tmp = abac_xmalloc(len);
+    if(cond)
+       sprintf(tmp,"%s:%s", name, cond);
+       else
+           sprintf(tmp,"%s", name);
+    return tmp;
+}
+
+/* len of name or name:cond */
+static int abac_param_len_with_condition(abac_param_t *ptr)
+{
+    char *cond=NULL;
+    char *name=ptr->name;
+    int len=strlen(name);
+    if(ptr->constraint) {
+       cond=ptr->constraint->string;
+       len=len+strlen(cond)+1;
+    }
+    return len;
+}
+
+/* just name */
+static char *abac_param_string(abac_param_t *ptr)
+{
+    return strdup(ptr->name);
+}
+
+/* just len of name */
+static int abac_param_len(abac_param_t *ptr)
+{
+    return strlen(ptr->name);
+}
+
+/* param1:cond1,param2:cond2 */
+char* abac_param_list_string_with_condition(abac_param_list_t *ptr)
+{
+    if(ptr->list == NULL)
+        return "";
+
+    abac_param_t  *cur;
+    char *tmp;
+    int len=0;
+    /* collect up all the lens so can allocate once */
+    abac_list_foreach(ptr->list, cur,
+           int l=abac_param_len_with_condition(cur);
+           len=len+l+1;
+    );
+    tmp=abac_xmalloc(len * sizeof(char));
+    /* collect up all the string */
+    int first=1;
+    abac_list_foreach(ptr->list, cur,
+           char *s=abac_param_string_with_condition(cur);
+           if(first) {
+               strcpy(tmp,s);
+               first=0;
+               } else {
+                  strcat(tmp,",");
+                  strcat(tmp,s);
+           }
+           free(s);
+    );
+    return tmp;
+}
+
+/* param1,param2 */
+char* abac_param_list_string(abac_param_list_t *ptr)
+{
+    abac_list_t *list=ptr->list;
+    if(list == NULL)
+        return "";
+    abac_param_t  *cur;
+    char *tmp;
+    int len=0;
+    /* collect up all the lens so can allocate once */
+    abac_list_foreach(list, cur,
+           // collect up the len
+           int l=abac_param_len(cur);
+           len=len+l+1;
+    );
+    tmp=abac_xmalloc(len * sizeof(char));
+    /* collect up all the string */
+    int first=1;
+    abac_list_foreach(list, cur,
+           char *s=abac_param_string(cur);
+           if(first) {
+               strcpy(tmp,s);
+               first=0;
+               } else {
+                  strcat(tmp,",");
+                  strcat(tmp,s);
+           }
+           free(s);
+    );
+    return tmp;
+}
Index: libabac/abac_pl_gen.c
===================================================================
--- libabac/abac_pl_gen.c	(revision 718ad9243faff3a00dea5c5c5b2ef6fe89caedbe)
+++ libabac/abac_pl_gen.c	(revision 718ad9243faff3a00dea5c5c5b2ef6fe89caedbe)
@@ -0,0 +1,335 @@
+
+
+/***********************************************************************/
+/* clause generation called from parser to generate credential clauses */
+/***********************************************************************/
+#include <stdio.h>
+#include <assert.h>
+#include <stdlib.h>
+
+#include "abac_set.h"
+#include "abac_util.h"
+#include "abac_pl.h"
+
+#include "uthash.h"
+
+// index to generate C1,C2..
+static int cred_count=0;
+extern char* abac_yyfptr;
+extern int abac_cnt_yy_id_certs();
+extern void abac_free_yy_id_certs();
+extern char *abac_string_yy_id_certs();
+char *abac_role_principal_cn(abac_role_t *role);
+char *abac_type_clauses=NULL;
+
+/***********************************************************************/
+static int _get_next_cred_idx()
+{
+    cred_count++;
+    return cred_count;
+}
+
+/* remember to free the returned string */
+static char *_compose_cred_list()
+{
+    int i=cred_count;;
+    if(cred_count==0) return "";
+
+    char *clist=(char *)abac_xmalloc(sizeof(char)*(cred_count)*3);
+    strcpy(clist,"C1");
+    if (cred_count==1) return clist;
+
+    i=1;
+    while(i!=cred_count) {
+        i++;
+        sprintf(clist,"%s,C%d",clist,i);
+    }
+    return clist;
+}
+
+
+/* generate role(p_name, r_name, param..) */
+static char* generate_pl_head_role_string(abac_role_t *role)
+{
+     char *tmp=NULL;
+     char *principalname=abac_role_principal_cn(role);
+     char *rolename=abac_role_role_name(role);
+     char *param_string=NULL;
+     int cnt=0;
+
+     /* can not be a linked role */
+     abac_param_list_t *role_params=abac_role_role_params(role);
+     if(role_params) {
+        param_string=abac_param_list_string(role_params);
+     }
+
+     if (param_string != NULL) {
+         cnt=asprintf(&tmp,"role(%s,%s,%s)", principalname, rolename, param_string);
+         free(param_string);
+         } else {
+             cnt=asprintf(&tmp,"role(%s,%s)", principalname, rolename);
+     }
+     if(cnt>0)
+        return tmp;
+        else
+           return NULL;
+}
+
+/* generate role(p_name, r_name, param..) with isMember call ?? */
+static char* generate_pl_tail_role_string(abac_role_t *role)
+{
+     char *tmp;
+     char *principalname=abac_role_principal_cn(role);
+     char *rolename=abac_role_role_name(role);
+     char *linkedname=abac_role_linked_role(role);
+
+     char *param_string=NULL;
+     char *linked_param_string=NULL;
+     int cnt=0;
+
+     abac_param_list_t *role_params=abac_role_role_params(role);
+     if(role_params) {
+        param_string=abac_param_list_string(role_params);
+     }
+
+     abac_param_list_t *linked_role_params=abac_role_linked_role_params(role);
+     if(linked_role_params) {
+        linked_param_string=abac_param_list_string(linked_role_params);
+     }
+
+     /* b.r.r */
+     if(linkedname!=NULL && rolename!=NULL && principalname!=NULL ) {
+         int fst=_get_next_cred_idx();
+         int snd=_get_next_cred_idx();
+         if(linked_param_string !=NULL) {
+             if (param_string != NULL) {
+                 cnt=asprintf(&tmp,"isMember(Y,role(%s,%s,%s),C%d),isMember(X,role(Y,%s,%s),C%d)",
+                            principalname,
+                            linkedname,linked_param_string,fst,
+                            rolename,param_string,snd);
+                 free(param_string);
+                 } else {
+                     cnt=asprintf(&tmp,"isMember(Y,role(%s,%s,%s),C%d),isMember(X,role(Y,%s),C%d)",
+                            principalname,
+                            linkedname,linked_param_string,fst,
+                            rolename,snd);
+             }
+             free(linked_param_string);
+             } else {
+                 if (role_params != NULL) {
+                     cnt=asprintf(&tmp,"isMember(Y,role(%s,%s),C%d),isMember(X,role(Y,%s,%s),C%d)",
+                            principalname,
+                            linkedname,fst,
+                            rolename,param_string,snd);
+                     free(param_string);
+                     } else {
+                         cnt=asprintf(&tmp,"isMember(Y,role(%s,%s),C%d),isMember(X,role(Y,%s),C%d)",
+                            principalname,
+                            linkedname,fst,
+                            rolename,snd);
+               }
+         }
+         if(cnt>0)
+             return tmp;
+             else
+                 return NULL;
+     } 
+     /* b.r */
+     if(linkedname==NULL && rolename!=NULL && principalname!=NULL ) {
+         int fst=_get_next_cred_idx();
+         if(param_string != NULL) {
+             cnt=asprintf(&tmp,"isMember(X,role(%s,%s,%s),C%d)",
+                          principalname, rolename, param_string, fst);
+             free(param_string);
+             } else {
+                 cnt=asprintf(&tmp,"isMember(X,role(%s,%s),C%d)",
+                          principalname, rolename, fst);
+         }
+         if(cnt>0)
+             return tmp;
+             else
+                 return NULL;
+     } 
+     /* b */
+     if(linkedname==NULL && rolename==NULL && principalname!=NULL ) {
+         tmp=abac_xstrdup(principalname);
+         return tmp;
+     } 
+
+     return tmp;
+}
+
+
+static char *generate_pl_rule_clause(char *head_role_string, abac_role_t *tail_role)
+{
+    char *tmp=NULL;
+    char* tail_role_string=NULL;
+    char* rolename=abac_role_role_name(tail_role);
+
+    if(rolename == NULL) {
+        /* A.R <- B */
+        tail_role_string=generate_pl_tail_role_string(tail_role);
+        if(tail_role_string != NULL) {
+            if(abac_type_clauses==NULL) {
+                asprintf(&tmp, "isMember(%s,%s,['%s'])",
+                         tail_role_string,head_role_string,abac_yyfptr);
+                } else {
+                    asprintf(&tmp, "isMember(%s,%s,['%s']) :- %s",
+                         tail_role_string,head_role_string,abac_yyfptr,
+                         abac_type_clauses);
+                    free(abac_type_clauses);
+                    abac_type_clauses=NULL;
+            }
+            } else { 
+                goto error;
+        }
+        } else {
+             /* A.R <- B.R */
+             /* A.R <- B.R.R */
+             tail_role_string=generate_pl_tail_role_string(tail_role);
+             if (cred_count==0) {
+                 if(abac_type_clauses==NULL) { 
+                     asprintf(&tmp,"isMember(X,%s,['%s']):-%s",
+                           head_role_string, abac_yyfptr, tail_role_string);
+                     } else {
+                         asprintf(&tmp,"isMember(X,%s,['%s']):-%s, %s",
+                                 head_role_string, abac_yyfptr,
+                                 tail_role_string, abac_type_clauses);
+                         free(abac_type_clauses);
+                         abac_type_clauses=NULL;
+                 }
+                 } else {
+                     char *tmp_cred_list=_compose_cred_list();
+                     if(abac_type_clauses == NULL) {
+                         asprintf(&tmp,"isMember(X,%s,L):-%s, appendL([['%s'],%s],L)", 
+                                  head_role_string, tail_role_string,
+                                  abac_yyfptr, tmp_cred_list);
+                         } else {
+                             asprintf(&tmp,"isMember(X,%s,L):-%s, appendL([['%s'],%s],L), %s", 
+                                  head_role_string, tail_role_string,
+                                  abac_yyfptr, tmp_cred_list, abac_type_clauses);
+                             free(abac_type_clauses);
+                             abac_type_clauses=NULL;
+                     }
+                     free(tmp_cred_list);
+                     cred_count=0;
+             }
+    }
+    if(tail_role_string) free(tail_role_string);
+    return tmp;
+
+error:
+    if(tail_role_string) free(tail_role_string);
+    return NULL;
+}
+
+static char *_add_string(char *dstr, char *nstr)
+{
+    if(strlen(dstr)==0) {
+        dstr=abac_xstrdup(nstr);
+        return dstr;
+        } else { 
+            int len = strlen(dstr)+strlen(nstr)+2;
+            char *tmp=abac_xmalloc(len*sizeof(char));
+            sprintf(tmp,"%s,%s", dstr,nstr);
+            free(dstr);
+            return tmp;
+    }
+    return NULL;
+}
+
+static char *generate_pl_intersecting_clause(char *head_role_string,
+                                                     abac_role_t *tail_role)
+{
+    char *tmp=NULL;
+    char* tail_role_string=NULL;
+    abac_list_t *list=abac_role_prereqs(tail_role);
+    /* A.R <- B.R & C.R.R */
+
+    if (list != NULL) {
+        abac_role_t *cur;
+        abac_list_foreach(list, cur,
+            char *ntmp=generate_pl_tail_role_string(cur);
+            if(tail_role_string==NULL)
+                 asprintf(&tail_role_string,"%s",ntmp);
+                 else
+                    asprintf(&tail_role_string,"%s, %s",tail_role_string,ntmp);
+            free(ntmp);
+        );
+    }
+
+    if (cred_count==0) {
+        if(abac_type_clauses ==NULL) {
+            asprintf(&tmp,"isMember(X,%s,['%s']):-%s",
+                   head_role_string, abac_yyfptr, tail_role_string);
+            } else {
+                asprintf(&tmp,"isMember(X,%s,['%s']):-%s, %s",
+                       head_role_string, abac_yyfptr, tail_role_string,
+                       abac_type_clauses);
+                free(abac_type_clauses);
+                abac_type_clauses=NULL;
+        }
+        } else {
+            char *tmp_cred_list=_compose_cred_list();
+            if(abac_type_clauses ==NULL) {
+                asprintf(&tmp,"isMember(X,%s,L):-%s, appendL([['%s'],%s],L)", 
+                                head_role_string, tail_role_string,
+                                abac_yyfptr, tmp_cred_list);
+                } else {
+                    asprintf(&tmp,"isMember(X,%s,L):-%s, appendL([['%s'],%s],L), %s", 
+                                head_role_string, tail_role_string,
+                                abac_yyfptr, tmp_cred_list,abac_type_clauses);
+                    free(abac_type_clauses);
+                    abac_type_clauses=NULL;
+            }
+            free(tmp_cred_list);
+            cred_count=0;
+    }
+    if(tail_role_string) free(tail_role_string);
+    return tmp;
+}
+
+/* generate the yap isMember rule clause for the credential stmt */
+abac_list_t *generate_pl_clauses(abac_role_t *head_role, abac_role_t *tail_role)
+{
+   char *tmp=NULL;
+   abac_list_t *clauses=abac_list_new();
+
+   int cnt=abac_cnt_yy_id_certs();
+   if(cnt > 0) { /* string it up */
+       abac_type_clauses=abac_string_yy_id_certs();
+       abac_free_yy_id_certs();
+   }
+
+/* generate head's role string */
+    char *head_role_string=generate_pl_head_role_string(head_role);
+    if(head_role_string == NULL)
+        goto error;
+
+/* tail side */
+    if(abac_role_is_intersection(tail_role)) {
+       tmp=generate_pl_intersecting_clause(head_role_string, tail_role);
+       } else {
+           tmp=generate_pl_rule_clause(head_role_string, tail_role);
+    }
+    if(tmp==NULL)
+        goto error;
+    abac_list_add(clauses,tmp);
+    return clauses;
+
+error:
+    if(head_role_string) free(head_role_string);
+    return clauses;
+}
+
+/* generate the yap isType rule clause for the type,
+   isType(Acme, keyid); */
+char *generate_pl_type_clause(char *principalname, int type)
+{
+    char *tmp=NULL;
+    char *typeid= abac_keyid_type(type);
+    int cnt=asprintf(&tmp,"isType(%s,%s)",
+                                principalname, typeid);
+    return tmp;
+}
+
Index: libabac/abac_rt.h
===================================================================
--- libabac/abac_rt.h	(revision 718ad9243faff3a00dea5c5c5b2ef6fe89caedbe)
+++ libabac/abac_rt.h	(revision 718ad9243faff3a00dea5c5c5b2ef6fe89caedbe)
@@ -0,0 +1,29 @@
+
+/************************************************
+ abac_rt.h
+************************************************/
+/* on yacc */
+extern FILE *abac_yyin, *abac_yyout;
+extern int yyparse();
+extern void abac_init_yy();
+extern char *abac_get_yap_clause();
+extern void abac_free_yap_clause();
+extern abac_role_t *abac_get_yap_head_role();
+extern void abac_free_yap_tail_role();
+extern abac_role_t *abac_get_yap_head_role();
+extern void abac_free_yap_tail_role();
+
+/* on lex */
+extern void abac_rest_yyin(FILE *);
+extern void abac_rest_yyout(FILE *);
+extern FILE *abac_get_yyin();
+extern FILE *abac_get_yyout();
+extern void abac_reset_yyfptr(char *);
+extern char* abac_get_yyfptr();
+
+/* on error code */
+
+#define ABAC_RT_ROLE_INVALID           -1  /* */
+#define ABAC_RT_CERT_INVALID           -2  /* */
+#define ABAC_RT_CERT_BAD_SIG           -3  /* */
+#define ABAC_RT_CERT_MISSING_ISSUER    -4  /* */
Index: libabac/abac_rt0.h
===================================================================
--- libabac/abac_rt0.h	(revision 53e540d5b3ba8b09dcdf1f90cf514182a491d9d3)
+++ 	(revision )
@@ -1,17 +1,0 @@
-
-/************************************************
-************************************************/
-/* on yacc */
-extern FILE *abac_yyin, *abac_yyout;
-extern int yyparse();
-extern void abac_init_yy();
-extern char *abac_get_yap_clause();
-extern char *abac_free_yap_clause();
-
-/* on lex */
-extern void abac_rest_yyin(FILE *);
-extern void abac_rest_yyout(FILE *);
-extern FILE *abac_get_yyin();
-extern FILE *abac_get_yyout();
-extern void abac_reset_yyfptr(char *);
-extern char* abac_get_yyfptr();
Index: libabac/ort0.l
===================================================================
--- libabac/ort0.l	(revision 53e540d5b3ba8b09dcdf1f90cf514182a491d9d3)
+++ 	(revision )
@@ -1,70 +1,0 @@
-%{
-#include <stdio.h>
-#include <string.h>
-#include "ort0.h"
-
-int debug=0;
-
-/* with yacc */
-extern YYSTYPE yylval; 
-/* with just lex */
-/* YYSTYPE yylval; */ 
-
-/* if using canned fixed test string */
-char INPUT_LINE[] = "usc.playground <- usc.employee.friend";
-char *yyfptr = INPUT_LINE; /* default */
-
-#undef YY_INPUT
-#define YY_INPUT(buf,result,max_size) \
-    { \
-    if(yyfptr != NULL) { \
-      char* c = strncpy(buf,yyfptr,max_size); \
-      if (max_size > 0) buf[max_size-1] = '\0'; \
-      if(strlen(yyfptr) > max_size) yyfptr = yyfptr + max_size-1;  \
-        else yyfptr=NULL; \
-      result = (c == NULL ) ? YY_NULL : strlen(buf); \
-      } else { \
-         buf[0] = '\0'; \
-         result = YY_NULL; \
-    } \
-    }
-
-void abac_reset_yyfptr(char *str) {
-    yyfptr=str;
-}
-
-char* abac_get_yyfptr() {
-    return yyfptr;
-}
-
-/* if using external file input, output */
-void abac_reset_yyin(FILE *new_yyin) {
-    yyin=new_yyin;
-}
-void abac_reset_yyout(FILE *new_yyout) {
-    yyout=new_yyout;
-}
-FILE *abac_get_yyin() {
-    if(yyin) return yyin;
-    else return stdin;
-}
-FILE *abac_get_yyout() {
-    if(yyout) return yyout;
-    else return stdout;
-}
-
-%}
-%%
-[a-zA-Z0-9][_a-zA-Z0-9]*    { yylval.string=strdup(yytext); 
-                          if(debug) fprintf(yyout,"IDEN ");
-                          return IDEN; }
-\<-                     { if(debug) fprintf(yyout,"DERIVE ");
-                          return DERIVE; }
-\.                      { if(debug) fprintf(yyout, "DOT " );
-                          return DOT; }
-&                       { if(debug) fprintf(yyout, "AND " );
-                          return AND; }
-\n                      { /* ignore end-of-line */; }
-[ \t]+                  { /* ignore whitespace */; }
-%%
-
Index: libabac/ort0.y
===================================================================
--- libabac/ort0.y	(revision 53e540d5b3ba8b09dcdf1f90cf514182a491d9d3)
+++ 	(revision )
@@ -1,201 +1,0 @@
-
-
-/* bison grammar rules for process old rt0 statements */
-/*
-   isi.employee <- ted
-   ted.friend <- mike
-   usc.employee <- isi.employee
-   usc.playground <- usc.employee.friend
-   query,
-      usc.playground <- ?Z
-      isi.playground <- mike
-*/
-
-%{
-/* C declarations */
-#include <stdio.h>
-#include <string.h>
-#include <abac_stack.h>
-
-extern char *abac_cn_with_sha(char*);
-
-FILE *abac_yyin = NULL;
-FILE *abac_yyout = NULL;
-char *abac_yap_clause = NULL;
-char *abac_yyfptr = NULL;
-/* index to generate, C1,C2 .. */
-int cred_count = 0;
-
-int sz_overhead = 0;
-
-char *compose_cred_list();
-int get_next_cred_idx();
-
-%}
-/* Bison declarations */
-%union {
-int  number;
-char *string;   /* For returning char strings */
-}
-%type <string> keypart rolepart left right term stmt
-
-%token <string> IDEN       /* keyname or rolename */
-
-%token  <operator>  DERIVE    "<-"
-%token  <operator>  DOT       "."
-%token  <operator>  AND       "&"
-
-%%
-/* Grammar rules */
-
-input:      /* empty */
-             { }
-        | stmt 
-             { fprintf (abac_yyout,"stmt (%s)\n", $1);
-               abac_yap_clause = $1;
-             }
- 
-stmt : left DERIVE right
-             { int sz;
-               char *ptr=strstr($3,"role(");
-               char *tmp;
-               if(ptr==NULL) {
-                 sz=strlen($3)+strlen($1)+sz_overhead;
-                 tmp=(char *)abac_xmalloc(sz);
-                 sprintf(tmp,"isMember(%s,%s,['%s'])",$3,$1,abac_yyfptr);
-               } else {
-                 sz=strlen($3)+strlen($1)+sz_overhead;
-                 tmp=(char *)abac_xmalloc(sz);
-                 if (cred_count==0) { 
-                     sprintf(tmp,"isMember(X,%s,['%s']):-%s",
-                                        $1, abac_yyfptr, $3);
-                     } else {
-                     char *tmp_cred_list=compose_cred_list();
-                     sprintf(tmp,"isMember(X,%s,L):-%s, appendL([['%s'],%s],L)",
-                                        $1, $3, abac_yyfptr, tmp_cred_list);
-                     free(tmp_cred_list);
-                     cred_count=0;
-                 }
-               }
-               $$=tmp;
-               free($3);free($1);
-             }
-
-left : keypart DOT rolepart
-             { 
-               int sz=strlen($1)+strlen($3)+sz_overhead;
-               char *tmp=(char *)abac_xmalloc(sz);
-               sprintf(tmp,"role(%s,%s)", $1, $3);
-               $$=tmp; 
-               free($3);free($1);
-             }
-/* isi */
-keypart : IDEN 
-             { 
-             char *cn=abac_cn_with_sha($1);
-             $$=strdup(cn);
-             }
-
-/* friend */
-rolepart : IDEN
-             { $$=strdup($1); }
-
-right : term
-             { $$=$1; }
-      | term AND right
-             { 
-               int sz=strlen($1)+strlen($3)+2;
-               char *tmp=(char *)abac_xmalloc(sz);
-               sprintf(tmp,"%s,%s",$1,$3);
-               $$=tmp; 
-               free($1);free($3);
-             }
-
-term : keypart DOT IDEN DOT IDEN
-             { 
-               int sz=strlen($1)+strlen($3)+strlen($5)+sz_overhead;
-               char *tmp=(char *)abac_xmalloc(sz);
-               int fst=get_next_cred_idx();
-               int snd=get_next_cred_idx();
-               sprintf(tmp,"isMember(Y,role(%s,%s),C%d),isMember(X,role(Y,%s),C%d)",$1,$3,fst,$5,snd);
-               $$=tmp; 
-               free($1);free($3);free($5);
-             }
-      | keypart DOT IDEN
-             { 
-               int sz=strlen($1)+strlen($3)+sz_overhead;
-               int fst=get_next_cred_idx();
-               char *tmp=(char *)abac_xmalloc(sz);
-               sprintf(tmp,"isMember(X,role(%s,%s),C%d)", $1, $3, fst);
-               $$=tmp; 
-               free($1);free($3);
-             }
-      | keypart
-             { 
-             $$=$1;
-             }
-
-%%
-#include "abac_rt0.h"
-
-/* Additional C code */
-int yywrap()
-{
-     /* exit when done lexing the current input */
-     return 1;
-} 
-
-int yyerror (char *s)
-{
-     fprintf (abac_yyout,"yyerror: %s\n", s);
-}
-
-/* setting defaults */
-void abac_yyinit()
-{
-    abac_yyin=abac_get_yyin();
-    abac_yyout=abac_get_yyout();
-    abac_yyfptr = abac_get_yyfptr();
-    sz_overhead = strlen(abac_yyfptr)+2000;
-} 
-
-char *abac_get_yap_clause()
-{
-    return abac_yap_clause;
-}
-
-char *abac_free_yap_clause()
-{
-    if (abac_yap_clause != NULL)
-        free(abac_yap_clause);
-}
-
-int get_next_cred_idx()
-{
-    printf("ZZZ count it once..%d\n", cred_count);
-    cred_count++;
-    return cred_count;
-}
-
-int get_curr_cred_idx()
-{
-    return cred_count;
-}
-
-/* remember to free the returned string */
-char *compose_cred_list()
-{
-    int i=cred_count;;
-    if(cred_count==0) return "";
-
-    char *clist=(char *)abac_xmalloc(sizeof(char)*(cred_count)*3);
-    strcpy(clist,"C1");
-    if (cred_count==1) return clist;
-
-    i=1;
-    while(i!=cred_count) {
-        i++;
-        sprintf(clist,"%s,C%d",clist,i);
-    }
-    return clist;
-}
Index: libabac/prover.c
===================================================================
--- libabac/prover.c	(revision 53e540d5b3ba8b09dcdf1f90cf514182a491d9d3)
+++ 	(revision )
@@ -1,41 +1,0 @@
-#include <err.h>
-#include <stdio.h>
-
-#include <abac.h>
-
-#include "options.h"
-
-int main(int argc, char **argv) {
-    int i, success;
-    abac_credential_t *cred;
-
-    options_t opts = { 0, };
-    get_options(argc, argv, &opts);
-
-    abac_context_t *ctx = abac_context_new();
-    abac_context_load_directory(ctx, opts.keystore);
-
-    printf("ASKING a question role(%s), principal(%s)\n\n", opts.role, opts.principal);
-    abac_credential_t **credentials = abac_context_query(ctx,
-        opts.role, opts.principal,
-        &success
-    );
-
-    if (success)
-        puts("success");
-
-    if (credentials != NULL)
-        for (i = 0; credentials[i] != NULL; ++i) {
-            cred = credentials[i];
-            printf("credential %s <- %s\n",
-                    abac_role_string(abac_credential_head(cred)),
-                    abac_role_string(abac_credential_tail(cred))
-                  );
-        }
-
-    abac_context_credentials_free(credentials);
-
-    abac_context_free(ctx);
-
-    return 0;
-}
Index: libabac/prover_plus.cc
===================================================================
--- libabac/prover_plus.cc	(revision 53e540d5b3ba8b09dcdf1f90cf514182a491d9d3)
+++ 	(revision )
@@ -1,38 +1,0 @@
-#include <err.h>
-#include <stdio.h>
-#include <vector>
-
-#include <abac.hh>
-
-#include "options.h"
-
-using namespace ABAC;
-using std::vector;
-
-int main(int argc, char **argv) {
-    int i;
-    abac_credential_t *cred;
-
-    options_t opts = { 0, };
-    get_options(argc, argv, &opts);
-
-    Context ctx;
-    ctx.load_directory(opts.keystore);
-
-    bool success;
-    vector<Credential> credentials = ctx.query(
-        opts.role, opts.principal,
-        success
-    );
-
-    if (success)
-        puts("success");
-    for (vector<Credential>::iterator i = credentials.begin(); i != credentials.end(); ++i) {
-        printf("credential %s <- %s\n",
-            i->head().string(),
-            i->tail().string()
-        );
-    }
-
-    return 0;
-}
Index: libabac/rt2.l
===================================================================
--- libabac/rt2.l	(revision 718ad9243faff3a00dea5c5c5b2ef6fe89caedbe)
+++ libabac/rt2.l	(revision 718ad9243faff3a00dea5c5c5b2ef6fe89caedbe)
@@ -0,0 +1,103 @@
+%{
+#include <stdio.h>
+#include <string.h>
+#include "rt2.h"
+
+static int debug=0;
+
+/* with yacc */
+extern YYSTYPE yylval; 
+/* with just lex */
+/* YYSTYPE yylval; */ 
+
+/* if using canned fixed test string */
+char INPUT_LINE[] = "usc.playground <- usc.employee.friend";
+char *yyfptr = INPUT_LINE; /* default */
+
+#undef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+    { \
+    if(yyfptr != NULL) { \
+      char* c = strncpy(buf,yyfptr,max_size); \
+      if (max_size > 0) buf[max_size-1] = '\0'; \
+      if(strlen(yyfptr) > max_size) yyfptr = yyfptr + max_size-1;  \
+        else yyfptr=NULL; \
+      result = (c == NULL ) ? YY_NULL : strlen(buf); \
+      } else { \
+         buf[0] = '\0'; \
+         result = YY_NULL; \
+    } \
+    }
+
+void abac_reset_yyfptr(char *str) {
+    yyfptr=str;
+}
+
+char* abac_get_yyfptr() {
+    return yyfptr;
+}
+
+/* if using external file input, output */
+void abac_reset_yyin(FILE *new_yyin) {
+    yyin=new_yyin;
+}
+
+void abac_reset_yyout(FILE *new_yyout) {
+    if(yyout) {
+      fflush(yyout);
+      fclose(yyout);
+    }
+    yyout=new_yyout;
+}
+
+void abac_flush_yyout() {
+    if(yyout)
+      fflush(yyout);
+}
+
+FILE *abac_get_yyin() {
+    if(yyin) return yyin;
+    else return stdin;
+}
+FILE *abac_get_yyout() {
+    if(yyout) return yyout;
+    else return stdout;
+}
+
+/* XXX need to add param's possible format and break it out from IDEN next */
+%}
+%%
+keyid                       { yylval.string=strdup(yytext);
+                              if(debug) fprintf(yyout," KEYTYPE ");
+                              return KEYTYPE; }
+role                        { if(debug) fprintf(yyout," ROLE ");
+                              return ROLE; }
+principal                   { if(debug) fprintf(yyout," PRINCIPAL ");
+                              return PRINCIPAL; }
+[a-zA-Z0-9][_a-zA-Z0-9]*    { yylval.string=strdup(yytext); 
+                              if(debug) fprintf(yyout," IDEN ");
+                                return IDEN; }
+\<-                         { if(debug) fprintf(yyout," DERIVE ");
+                                return DERIVE; }
+\.                          { if(debug) fprintf(yyout, " DOT " );
+                                return DOT; }
+&                           { if(debug) fprintf(yyout, " AND " );
+                                return AND; }
+,                           { if(debug) fprintf(yyout, " COMMA ");
+                                return COMMA; }
+\(                          { if(debug) fprintf(yyout, " LPAREN ");
+                                return LPAREN; }
+\)                          { if(debug) fprintf(yyout, " RPAREN ");
+                                return RPAREN; }
+\[                          { if(debug) fprintf(yyout, " LSQUARE ");
+                                return LSQUARE; }
+\]                          { if(debug) fprintf(yyout, " RSQUARE ");
+                                return RSQUARE; }
+\:                          { if(debug) fprintf(yyout, " COLON ");
+                                return COLON; }
+\?                          { if(debug) fprintf(yyout, " QMARK ");
+                                return QMARK; }
+\n                          { /* ignore end-of-line */; }
+[ \t]+                      { /* ignore whitespace */; }
+%%
+
Index: libabac/rt2.y
===================================================================
--- libabac/rt2.y	(revision 718ad9243faff3a00dea5c5c5b2ef6fe89caedbe)
+++ libabac/rt2.y	(revision 718ad9243faff3a00dea5c5c5b2ef6fe89caedbe)
@@ -0,0 +1,304 @@
+
+/* bison grammar rules for process new rt1 statements */
+
+/*
+   [keyid:isi].role:employee <- [keyid:ted]
+   [keyid:ted].role:friend <- [keyid:mike]
+   [keyid:usc].role:employee <- [keyid:isi].role:employee
+   [keyid:usc].role:playground <- [keyid:usc].role:employee.role:friend
+   query,
+      [keyid:isi].role:playground <- [keyid:?Z]
+      [keyid:isi].role:playground <- [keyid:mike]
+
+USC.evaluatorOf(this)<-USC.managerOf(this)
+USC.managerOf(this)<-USC.employee
+ISI.managerOf(Maryann) <- John
+USC.employee <- ISI.employee
+ISI.employee  <- Maryann
+ISI.employee <- John
+
+USC.employee <-?- John
+USC.evaluatorOf(Maryann)<-?- John
+*/
+
+%{
+// include the GNU extension of asprintf
+#define _GNU_SOURCE
+
+/* C declarations */
+#include <stdio.h>
+#include <string.h>
+
+#include "abac_pl_yy.h"
+
+int yyerror (char *s);
+
+FILE *abac_yyin = NULL;
+FILE *abac_yyout = NULL;
+char *abac_yyfptr = NULL;
+
+static int sz_overhead = 0;
+static int abac_yy_error_code = 0; /* keeping last error code */
+
+void panic(char *msg);
+ 
+extern void set_yap_clauses(abac_list_t *);
+extern abac_list_t *make_statement(abac_yy_role_expression_t *,
+           abac_yy_role_expression_t *);
+extern abac_yy_role_expression_t *make_yy_role_expression(int,
+           abac_yy_principal_t *, abac_yy_role_t *, abac_yy_role_t *);
+extern abac_yy_principal_t *make_yy_principal(char *, char *, int);
+extern abac_yy_role_t *make_yy_role(char *, abac_yy_dterm_t *);
+extern abac_yy_param_data_t *make_yy_param_data(char*, int);
+extern abac_yy_param_principal_t *make_yy_param_principal(char*);
+extern abac_yy_dterm_t *make_yy_dterm_anonymous();
+extern abac_yy_dterm_t *make_yy_dterm_principal(abac_yy_param_principal_t *);
+extern abac_yy_dterm_t *make_yy_dterm_named(abac_yy_principal_t *);
+extern abac_yy_dterm_t *make_yy_dterm_data(abac_yy_param_data_t *);
+extern char *abac_cn_with_sha(char*);
+extern abac_yy_dterm_t *add_yy_dterm(abac_yy_dterm_t *, abac_yy_dterm_t *);
+extern abac_yy_role_expression_t *add_yy_role_expression(
+                abac_yy_role_expression_t *, abac_yy_role_expression_t *);
+extern void set_yy_param_data_is_variable(abac_yy_param_data_t *);
+extern void abac_init_yy_id_certs();
+
+%}
+/* Bison declarations */
+%union {
+struct _abac_yy_principal_t *pstruct;
+struct _abac_yy_param_principal_t *ppstruct;
+struct _abac_yy_param_data_t *pdstruct;
+struct _abac_yy_role_t *rstruct;
+struct _abac_yy_dterm_t *dstruct;
+struct _abac_yy_role_expression_t *estruct;
+struct abac_list_t *lstruct;
+char *string;   /* For returning char strings */
+}
+%type <lstruct> stmt
+%type <rstruct> rolepart 
+%type <estruct> left 
+%type <estruct> right 
+%type <estruct> roleterm 
+%type <pstruct> keypart
+%type <dstruct> dterms
+%type <dstruct> dterm
+%type <pdstruct> typedpart
+%type <ppstruct> principalpart
+
+%token <string> IDEN            /* keyname or rolename */
+%token <string> ROLE            /* the word, role */
+%token <string> PRINCIPAL       /* the word, principal */
+%token <string> KEYTYPE         /* keyid | or something else */
+
+%token  <operator>  DERIVE    "<-"
+%token  <operator>  DOT       "."
+%token  <operator>  AND       "&"
+%token  <operator>  LPAREN    "("
+%token  <operator>  RPAREN    ")"
+%token  <operator>  LSQUARE   "["
+%token  <operator>  RSQUARE   "]"
+%token  <operator>  LANGLE    "<"
+%token  <operator>  RANGLE    ">"
+%token  <operator>  COLON     ":"
+%token  <operator>  COMMA     ","
+%token  <operator>  QMARK     "?"
+
+%%
+/* Grammar rules */
+
+input:      /* empty */
+             { }
+        | stmt 
+             {  
+               set_yap_clauses($1);
+             }
+ 
+/* generate/concate prolog credentials clauses */
+stmt : left DERIVE right
+             { 
+               abac_yy_role_expression_t *headexpr=$1;
+               abac_yy_role_expression_t *tailexpr=$3;
+               abac_list_t *ret=make_statement(headexpr, tailexpr);
+               if(ret == NULL) {
+                   panic("unable to parse the rule statment");
+                   YYERROR;
+                   } else {
+                       $$=ret;
+               }
+             }
+/*
+   [keyid:isi].role:modifyBy([keyid:mike])
+   [keyid:acme].role:preferred
+*/
+left : keypart DOT rolepart
+             { 
+               abac_yy_principal_t *keypart=$1;
+               abac_yy_role_t *rolepart=$3;
+               abac_yy_role_expression_t *expr=
+                         make_yy_role_expression(EXPR_ROLE,keypart,rolepart,NULL);
+               $$=expr;
+             }
+
+/* [keyid:mike] */
+keypart : LSQUARE KEYTYPE COLON IDEN RSQUARE 
+             { 
+               char *cn=abac_cn_with_sha($4);
+               int idtype=abac_verify_keyid_type($2);
+               if(cn && idtype)  {
+                 $$=make_yy_principal($4, cn, idtype);
+                 } else {
+                   panic("encountered an invalid SHA id");
+                   YYERROR;
+               }
+             }
+/* 
+   role:modifyBy([keyid:mike],[keyid:ted])
+   role:modifyBy([keyid:mike])
+   role:preferred
+*/
+rolepart : ROLE COLON IDEN LPAREN dterms RPAREN
+             { 
+               $$=make_yy_role($3,$5);
+             }
+       | ROLE COLON IDEN
+             { 
+               $$=make_yy_role($3,NULL);
+             }
+
+/*
+   [keyid:mike],[keyid:ted]
+   [keyid:mike]
+   [principal:?Z]
+??   [principal:?this]
+   [int:99]
+   [int:?Z]
+   [?]
+*/
+dterms : dterm COMMA dterms
+             {
+               abac_yy_dterm_t *nterm=$1;
+               abac_yy_dterm_t *dterms=$3;
+               $$=add_yy_dterm(nterm, dterms);
+             }
+      | dterm
+             {
+               $$=$1;
+             }
+
+/* XX need to handdle principal:?X dterm ??? */
+dterm : LSQUARE QMARK RSQUARE 
+             { $$= make_yy_dterm_anonymous(); }
+      | keypart 
+             { $$= make_yy_dterm_named($1); }
+      | principalpart
+             { $$= make_yy_dterm_principal($1); }
+      | typedpart
+             { $$= make_yy_dterm_data($1); }
+
+typedpart : LSQUARE IDEN COLON IDEN RSQUARE 
+             {
+               int type=abac_verify_dterm_type($2); 
+               if (type) {
+                 $$ = make_yy_param_data($4, type); 
+                 } else {
+                   panic("wrong type in data dterm!!");
+                   YYERROR;
+               }
+             }
+       | LSQUARE IDEN COLON QMARK IDEN RSQUARE 
+             {
+               int type=abac_verify_dterm_type($2); 
+               if (type) {
+                 abac_yy_param_data_t *ptr=make_yy_param_data($5, type); 
+                 set_yy_param_data_is_variable(ptr);
+                 $$=ptr;
+                 } else {
+                   panic("wrong type in data dterm!!");
+                   YYERROR;
+               }
+             }
+
+/* [principal:?Z] */
+principalpart : LSQUARE PRINCIPAL COLON QMARK IDEN RSQUARE 
+             {
+               $$ = make_yy_param_principal($5); 
+             }
+
+right : roleterm AND right
+             { 
+               abac_yy_role_expression_t *nexpr=$1;
+               abac_yy_role_expression_t *exprs=$3;
+               $$=add_yy_role_expression(nexpr,exprs);
+             }
+      | roleterm
+             { $$=$1; }
+
+/* role at tail/right side 
+  [keyid:usc].role:employee.role:friend
+  [keyid:usc].role:worker
+  [keyid:mike]
+*/
+roleterm : keypart DOT rolepart DOT rolepart
+             { 
+               abac_yy_principal_t *keypart=$1;
+               abac_yy_role_t *linked_rolepart=$3;
+               abac_yy_role_t *rolepart=$5;
+               abac_yy_role_expression_t *expr=
+                   make_yy_role_expression(EXPR_LINKED,keypart,rolepart,linked_rolepart);
+               $$=expr;
+             }
+      | keypart DOT rolepart
+             { 
+               abac_yy_principal_t *keypart=$1;
+               abac_yy_role_t *rolepart=$3;
+               abac_yy_role_expression_t *expr=
+                   make_yy_role_expression(EXPR_ROLE,keypart,rolepart,NULL);
+               $$=expr;
+             }
+      | keypart
+             { 
+               abac_yy_principal_t *keypart=$1;
+               abac_yy_role_expression_t *expr=
+                   make_yy_role_expression(EXPR_NAMED,keypart,NULL,NULL);
+               $$=expr;
+             }
+%%
+
+/* Additional C code */
+int yywrap()
+{
+     /* exit when done lexing the current input */
+     return 1;
+} 
+
+int yyerror (char *s)
+{
+     fprintf (abac_yyout,"yyerror: %s\n", s);
+}
+
+/* setting defaults */
+void abac_yyinit()
+{
+    abac_yyin=abac_get_yyin();
+    abac_yyout=abac_get_yyout();
+    abac_yyfptr = abac_get_yyfptr();
+    sz_overhead = strlen(abac_yyfptr)+2000;
+    abac_init_yap_id_clauses();
+    abac_init_yy_id_certs();
+} 
+
+void panic(char *msg) 
+{
+     yyerror(msg);
+}
+
+void set_error_code(int v)
+{
+     abac_yy_error_code=v;
+}
+
+static int get_error_code()
+{
+     return abac_yy_error_code;
+}
+
