/* $Id$ */

/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* 
* http://www.apache.org/licenses/LICENSE-2.0
* 
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* 
**  mod_authz_annotate.c -- Apache sample authz_annotate module
**  [Autogenerated via ``apxs -n authz_annotate -g'']
**
**  To play with this sample module, first compile it into a
**  DSO file and install it into Apache's libexec directory 
**  by running:
**
**    $ apxs -c -i mod_authz_annotate.c
**
**  Then activate it in Apache's apache.conf file, for instance
**  for the URL /authz_annotate, as follows:
**
**    #   apache.conf
**    LoadModule authz_annotate_module libexec/mod_authz_annotate.so
**    <Location /authz_annotate>
**    SetHandler authz_annotate
**    </Location>
**
**  Then after restarting Apache via
**
**    $ apachectl restart
**
**  you immediately can request the URL /%NAME and watch for the
**  output of this module. This can be achieved for instance via:
**
**    $ lynx -mime_header http://localhost/authz_annotate 
**
**  The output should be similar to the following one:
**
**    HTTP/1.1 200 OK
**    Date: Tue, 31 Mar 1998 14:42:22 GMT
**    Server: Apache/1.3.4 (Unix)
**    Connection: close
**    Content-Type: text/html
**  
**    The sample page from mod_authz_annotate.c
*/ 


/* Apache configuration merging strategy:
 *
 * Apache processes <Location> directives in the order in which they
 * appear in the configuration file(s).
 * The merge_config() code below now takes each
 * successive <Location> directive which specifies a given
 * mod_authz_annotate configuration, with one or more authority urls
 * to contact and takes the unique union of those authorities.  If the
 * configurations ask for different combinations of ACLs and IDs, the
 * system favors asking for ACLs and IDs over not (so if one requests
 * it, and the other does not, the union will be to request it).
 *
 *
 * For example given the configuration below:
 *
 * <Location /clients/search/services/saved-search/JSON>
 *  AuthzAnnotateEnable  On
 *  AuthzAnnotateIDAclAuthority http://localhost:7039/UserACLs
 * </Location>
 *
 * <Location /clients/search>
 *  AuthzAnnotateEnable  On
 *  AuthzAnnotateIDAclAuthority http://localhost:7039/UserACLs
 * </Location>
 *
 */


// global for the current process to track if curl initialization failed
static int curl_init_failed;

#include "httpd.h"
#include "http_config.h"
#include "http_log.h"
#include "http_protocol.h"
#include "http_request.h"
#include "ap_config.h"

#include "constants.h"

#include <stdio.h>

#include <curl/curl.h>

#define MODULE_NAME "mod_authz_annotate"
#define MODULE_VERSION "4.6.0"

#define HERE() fprintf(stderr, "\n" __FILE__ ":%d\n\n", __LINE__);

static const char __rcsid_v_[] __attribute__((__unused__)) = "\100(#)" "$Id$";

#define PARAM_USERNAME   "username"
#define PARAM_ID_NEEDED  "idneeded"
#define PARAM_ACL_NEEDED "aclneeded"

#define TRUE_STRING     "true"
#define FALSE_STRING    "false"

/* These are the prefixes for user id and for acl tokens, expected back from the authority services
 */
#define ID_PREFIX "ID:"
#define TOKEN_PREFIX "TOKEN:"
#define UNREACHABLE_PREFIX "UNREACHABLEAUTHORITY:"
#define NOTFOUND_PREFIX "USERNOTFOUND:"
#define UNAUTHORIZED_PREFIX "UNAUTHORIZED:"
#define AUTHORIZED_PREFIX "AUTHORIZED:"

/*
  Structure that holds all the connect urls
*/
struct ConfigURL {
  struct ConfigURL* next;
  char* connecturl;
  int idneeded;
  int aclneeded;
};

/*
  Configuration information structure.
*/
struct Config {
  int activated;
  int infer_service_authz;
  // explicit flags are used to favor explicit setting of the flag on over a
  // default off when merging configs, while still allowing explicit off to work
  int activated_explicit;
  int infer_service_authz_explicit;
  struct ConfigURL* first;
};


/*************************************************************************** 
 Macros To Ease Compatibility
 ***************************************************************************/
#ifdef STANDARD20_MODULE_STUFF
#include <apr_strings.h>

#define APR_POOL_T apr_pool_t
#define APR_TABLE_T apr_table_t
#define APR_ARRAY_HEADER_T apr_array_header_t
#define APR_TABLE_ENTRY_T apr_table_entry_t
#define APACHE_REQUEST_USER r->user

#define log_rerror(file_line, level, r, fmt, rest...) \
  ap_log_rerror(file_line, level | APLOG_NOERRNO, 0, r, fmt , ## rest);

#else

#define APR_POOL_T pool
#define APR_TABLE_T table
#define APR_ARRAY_HEADER_T array_header
#define APR_TABLE_ENTRY_T table_entry
#define APACHE_REQUEST_USER r->connection->user

#define apr_psprintf               ap_psprintf
#define apr_pstrcat                ap_pstrcat
#define apr_palloc                 ap_palloc
#define apr_pcalloc                ap_pcalloc
#define apr_table_make             ap_make_table
#define apr_table_add              ap_table_add
#define apr_table_get              ap_table_get
#define apr_table_set              ap_table_set
#define apr_table_elts             ap_table_elts
#define apr_table_unset            ap_table_unset
#define apr_is_empty_table         ap_is_empty_table

#define log_rerror(file_line, level, r, fmt, rest...) \
  ap_log_rerror(file_line, level | APLOG_NOERRNO, r, fmt , ## rest);

#endif /* STANDARD20_MODULE_STUFF */

/*
  Dynamic data accumulation structure.
*/
struct DataBlock {
  int length;
  void* buffer;
  int capacity;
  struct DataBlock* next;
};

struct DataBuffer {
  struct APR_POOL_T* p;
  struct DataBlock* first;
  struct DataBlock* last;
};

struct DataIterator {
  struct DataBlock* currentBlock;
  int currentOffset;
};


#ifdef STANDARD20_MODULE_STUFF
module AP_MODULE_DECLARE_DATA authz_annotate_module;
#else
module MODULE_VAR_EXPORT authz_annotate_module;
#endif

/* Take two lists of connecturls, take the list new and insert it into
 * merge.  If the connecturl is not in merge add it.  If the
 * connecturl is already in merge, union the requested parameters (if
 * either reqested an id/acl request the id/acl).
 */
static
void
merge_url_lists(APR_POOL_T *p, struct Config *merge, const struct Config *new) {
  struct ConfigURL* new_iter;
  struct ConfigURL* merge_iter;
  
  // for every entry in the new list
  for(new_iter = new->first; new_iter != NULL; new_iter = new_iter->next) {    

    // search for it in the merged list
    int found = FALSE;
    for(merge_iter = merge->first; merge_iter != NULL; merge_iter = merge_iter->next) {

      // if we find the new url in the merge list
      if (! strcmp(new_iter->connecturl, merge_iter->connecturl)) {
        merge_iter->idneeded = merge_iter->idneeded || new_iter->idneeded;
        merge_iter->aclneeded = merge_iter->aclneeded || new_iter->aclneeded;
        found = TRUE;
        break;
      }
    }
    
    // if the url was not found add it
    if (!found) {
      struct ConfigURL* copyURL = (struct ConfigURL*) apr_pcalloc(p, sizeof(struct ConfigURL));
      copyURL->connecturl = new_iter->connecturl;
      copyURL->idneeded = new_iter->idneeded;
      copyURL->aclneeded = new_iter->aclneeded;
      copyURL->next = merge->first;
      merge->first = copyURL;
    }
  }
}

/* insert connecturl into authority list.  if the connecturl is not
 * already in the list add it.  if it is in the list already union the
 * requested parameters (if either requested an id/acl request the
 * id/acl).
 */
static
void
insert_url_into_list(APR_POOL_T *p, struct Config *list, char *connecturl, const int idneeded, const int aclneeded) {
  struct ConfigURL* list_iter;
  
  // search for it in the merged list
  int found = FALSE;
  for(list_iter = list->first; list_iter != NULL; list_iter = list_iter->next) {
    
    // if we find the new url in the list list
    if (! strcmp(connecturl, list_iter->connecturl)) {
      list_iter->idneeded = list_iter->idneeded || idneeded;
      list_iter->aclneeded = list_iter->aclneeded || aclneeded;
      found = TRUE;
      break;
    }
  }

  if (!found) {
    struct ConfigURL* record = (struct ConfigURL*)apr_pcalloc(p, sizeof(struct ConfigURL));
    record->connecturl = connecturl;
    record->idneeded = idneeded;
    record->aclneeded = aclneeded;
    record->next = list->first;
    list->first = record;
  }
}

/* Set whether this mod is activated.
 */
static
const char*
activation_flag_cmd(cmd_parms *parms, void *mconfig, int flag) {
  struct Config* cfg = (struct Config*)mconfig;
  cfg->activated = flag;
  cfg->activated_explicit = 1;
  return NULL;
}

/* Set whether old-style service authz should be inferred
 */
static
const char*
infer_service_authz_cmd(cmd_parms *parms, void *mconfig, int flag) {
  struct Config* cfg = (struct Config*)mconfig;
  cfg->infer_service_authz = flag;
  cfg->infer_service_authz_explicit = 1;
  return NULL;
}

/* Set the hostname; no id requested but acls requested.
 */
static
const char*
connecturl_noid_yesacl_cmd(cmd_parms* parms, void* mconfig, char* string) {
  struct Config* cfg = (struct Config*)mconfig;
  // Add a new record to the start of the string
  APR_POOL_T* p = parms->pool;
  insert_url_into_list(p, cfg, string, FALSE, TRUE);
  return NULL;
}

/* Set the hostname; id requested but acls not requested.
 */
static
const char*
connecturl_yesid_noacl_cmd(cmd_parms* parms, void* mconfig, char* string) {
  struct Config* cfg = (struct Config*)mconfig;
  // Add a new record to the start of the string
  APR_POOL_T * p = parms->pool;
  insert_url_into_list(p, cfg, string, TRUE, FALSE);
  return NULL;
}

/* Set the hostname; id requested and acls requested.
 */
static
const char*
connecturl_yesid_yesacl_cmd(cmd_parms* parms, void* mconfig, char* string) {
  struct Config* cfg = (struct Config*)mconfig;
  // Add a new record to the start of the string
  APR_POOL_T* p = parms->pool;
  insert_url_into_list(p, cfg, string, TRUE, TRUE);
  return NULL;
}

/* Create a configuration record for a given dir.
 */
static
void*
create_config(APR_POOL_T *p, char *dir) {
  struct Config* cfg = (struct Config*) apr_pcalloc(p, sizeof(struct Config));
  cfg->activated = cfg->activated_explicit = 0;
  cfg->infer_service_authz = cfg->infer_service_authz_explicit = 0;
  cfg->first = NULL;
  return (void *) cfg;
}

/* Merge two configuration records for a given dir.
 */
static
void*
merge_config(APR_POOL_T *p, void* base_conf, void* new_conf) {
  // According to apache, we can't modify base_conf and new_conf here, so make a copy
  struct Config* cfg = (struct Config*) apr_pcalloc(p, sizeof(struct Config));
  struct Config* oldguy = (struct Config*)base_conf;
  struct Config* newguy = (struct Config*)new_conf;

  // If old conf had explicit params and newconf doesn't, use old; otherwise use new
  // (this way later blocks can explicitly turn it off, but will keep switches from
  // earlier blocks if later blocks just use the defaults)
  cfg->activated =
        (oldguy->activated_explicit && (!newguy->activated_explicit)) ?
        oldguy->activated : newguy->activated;
  cfg->infer_service_authz =
        (oldguy->infer_service_authz_explicit && (!newguy->infer_service_authz_explicit)) ?
        oldguy->infer_service_authz : newguy->infer_service_authz;
  cfg->activated_explicit =
        oldguy->activated_explicit || newguy->activated_explicit;
  cfg->infer_service_authz_explicit =
        oldguy->infer_service_authz_explicit || newguy->infer_service_authz_explicit;

  cfg->first = NULL;
  if (oldguy->first != NULL) {
    if (newguy->first != NULL) {
      // if both lists have something merge them both
      merge_url_lists(p, cfg, oldguy);
      merge_url_lists(p, cfg, newguy);
    }
    else {
      // if new is empty; copy old
      cfg->first = oldguy->first;
    }
  }
  else if (newguy->first != NULL) {
    // if old is empty copy new
    cfg->first = newguy->first;
  }

  return cfg;
}

/* Support method for writing request stream.
 */
static
size_t
write_data(void *ptr, size_t size, size_t nmemb, void *stream) {
  struct DataBuffer* dataBuffer = (struct DataBuffer*)stream;
  int remainingAmount = size * nmemb;
  while (1) {
    int amountToCopy;

    if (remainingAmount == 0) {
      break;
    }

    if (dataBuffer->last == NULL || dataBuffer->last->capacity == dataBuffer->last->length) {
      struct DataBlock* newBlock;

      // Allocate new block
      newBlock = (struct DataBlock*)apr_palloc(dataBuffer->p,sizeof(struct DataBlock));
      newBlock->next = NULL;
      newBlock->length = 0;
      newBlock->capacity = 4096;
      newBlock->buffer = (void *)apr_palloc(dataBuffer->p,newBlock->capacity);
      if (dataBuffer->last == NULL) {
        dataBuffer->last = newBlock;
        dataBuffer->first = newBlock;
      }
      else {
        dataBuffer->last->next = newBlock;
        dataBuffer->last = newBlock;
      }
    }

    // See if the remaining amount fits or not
    amountToCopy = dataBuffer->last->capacity - dataBuffer->last->length;
    if (amountToCopy > remainingAmount) {
      amountToCopy = remainingAmount;
    }
    memcpy(((unsigned char*)dataBuffer->last->buffer)+dataBuffer->last->length,ptr,amountToCopy);
    ptr = ((unsigned char*)ptr) + amountToCopy;
    dataBuffer->last->length += amountToCopy;
    remainingAmount -= amountToCopy;
  }
  return nmemb;
}

/* Method to initialize a buffer iterator
 */
static
void
iterator_initialize(struct DataIterator* di, struct DataBuffer* dataBuffer) {
  di->currentBlock = dataBuffer->first;
  di->currentOffset = 0;
}

/* Method to read the next line.
 * Return null if end.
 */
static
char*
iterator_getline(struct DataIterator* di, request_rec* r) {
  // Find length first
  // This is so we can be precise about allocating each string

  int length;
  struct DataBlock* current;
  int currentPos;
  char* stringBuffer;
  char* pointer;

  current = di->currentBlock;
  length = 0;
  currentPos = di->currentOffset;
  while(1) {
    char x;

    if (current == NULL) {
      if (length == 0) {
        return NULL;
      }
      break;
    }

    // log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, r, "Scanning a block of length %i", current->length);

    x = ((char*)current->buffer)[currentPos++];
    // log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, r, "character: %i", (int)x);
    if (currentPos == current->length) {
      current = current->next;
      currentPos = 0;
    }
    if (x == '\n') {
      break;
    }
    if (x == '\r') {
      continue;
    }
    length++;
  }


  // Allocate a string and fill it
  stringBuffer = (char*)apr_palloc(r->pool,(length+1)*sizeof(char));
  pointer = stringBuffer;
  while(1) {
    char x;   

    if (di->currentBlock == NULL){
      break;
    }

    x = ((char*)di->currentBlock->buffer)[di->currentOffset++];
    if (di->currentOffset == di->currentBlock->length) {
      di->currentBlock = di->currentBlock->next;
      di->currentOffset = 0;
    }
    if (x == '\n') {
      break;
    }
    if (x == '\r') {
      continue;
    }
    *pointer++ = x;
  }
  *pointer = 0;

  return stringBuffer;
}


/* Check if a prefix matches a string
 */
static
int
prefix_matches(const char* prefix, const char* string) {
  if (strlen(prefix) > strlen(string)) {
    return FALSE;
  }
  while(1) {
    if (*prefix == 0) {
      return TRUE;
    }
    if (*prefix++ != *string++) {
      return FALSE;
    }
  }
}


/* Do the work of talking to the service, and getting groups back.
 */
static
int
authz_annotate_users_and_groups(request_rec *r,
                                const char *userName,
                                APR_TABLE_T *userTable,
                                APR_TABLE_T *groupTable,
                                APR_TABLE_T *warningTable) {
  CURLcode curl_error_code;
  struct DataBuffer dataBuffer;
  char* escapedUserName;
  CURL *curl_handle;
  char* urlString;
  struct Config* cfg;
  int rval = DECLINED;
  int isKnown;
  struct ConfigURL* currentURL;
  const char * auth_line = NULL;
  const char * auth_type = NULL;
  struct curl_slist * headers = NULL;

  cfg = (struct Config*) ap_get_module_config(r->per_dir_config, &authz_annotate_module);

  if(curl_init_failed) {
    log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_ERR, r, "CURL global initialization failed");
    return HTTP_INTERNAL_SERVER_ERROR;
  }
  
  curl_handle = curl_easy_init();
  if (curl_handle == NULL) {
    log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_ERR, r, "CURL easy init failed");
    return HTTP_INTERNAL_SERVER_ERROR;
  }

  /* no progress meter */
  curl_error_code = curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 1);
  if (curl_error_code != CURLE_OK) {
    log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_ERR, r, "CURL easy set opt failed: %s", curl_easy_strerror(curl_error_code));
    curl_easy_cleanup(curl_handle);
    return HTTP_INTERNAL_SERVER_ERROR;    
  }

  
  curl_error_code = curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_data);
  if (curl_error_code != CURLE_OK) {
    log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_ERR, r, "CURL easy set opt failed: %s", curl_easy_strerror(curl_error_code));
    curl_easy_cleanup(curl_handle);
    return HTTP_INTERNAL_SERVER_ERROR;    
  }
  
  curl_error_code = curl_easy_setopt(curl_handle, CURLOPT_FILE, &dataBuffer);
  if (curl_error_code != CURLE_OK) {
    log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_ERR, r, "CURL easy set opt failed: %s", curl_easy_strerror(curl_error_code));
    curl_easy_cleanup(curl_handle);
    return HTTP_INTERNAL_SERVER_ERROR;    
  }
  
  auth_line = apr_table_get(r->headers_in, "Authorization");
  if (auth_line != NULL) {
    /* ap_getword_white returns the first whitespace-delimited word in
       auth_line, or NULL if no non-whitespace is found. */
    auth_type = ap_getword_white(r->pool, &auth_line);
  }

  /* Check to see if the client sent RFC 4459 SPNEGO authorization
     data. If so, we need to pass the Authorization header to the
     authority service so that it can be decoded.  Active Directory
     authorization needs this so that it can get group memberships
     from the Kerberos PAC. */
  if (auth_line != NULL && auth_type != NULL && strcasecmp(auth_type, "Negotiate") == 0) {
    char * authhdr = apr_psprintf(r->pool, "Authorization: %s", auth_line);
    if (authhdr == NULL) {
      log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_ERR, r, "apache failed to allocate Authorization header");
      curl_easy_cleanup(curl_handle);
      return HTTP_INTERNAL_SERVER_ERROR;
    }

    headers = curl_slist_append(NULL, authhdr);
    if (headers == NULL) {
      log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_ERR, r, "CURL failed to allocated slist");
      curl_easy_cleanup(curl_handle);
      return HTTP_INTERNAL_SERVER_ERROR;
    }
    
    curl_error_code = curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, headers);
    if(curl_error_code != CURLE_OK) {
      log_rerror( APLOG_MARK, APLOG_DEBUG|APLOG_ERR, r, "CURL easy set opt failed: %s", curl_easy_strerror(curl_error_code));
      curl_slist_free_all(headers);
      curl_easy_cleanup(curl_handle);
      return HTTP_INTERNAL_SERVER_ERROR;
    }
  }
  else {
    /* Do not include header data in buffer */
    curl_error_code = curl_easy_setopt( curl_handle, CURLOPT_HEADER, (long)0);
    if( curl_error_code != CURLE_OK ) {
      log_rerror( APLOG_MARK, APLOG_DEBUG|APLOG_ERR, r, "CURL easy set opt failed: %s", curl_easy_strerror(curl_error_code));
      curl_easy_cleanup(curl_handle);
      return HTTP_INTERNAL_SERVER_ERROR;
    }
  }

  escapedUserName = curl_escape(userName,strlen(userName));
  if (escapedUserName == NULL) {
    log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_ERR, r, "curl escape username failed");
    curl_slist_free_all(headers);
    curl_easy_cleanup(curl_handle);
    return HTTP_INTERNAL_SERVER_ERROR;    
  }

  // Grab the start of the list of authorities  
  currentURL = cfg->first;

  // If there are no authorities, the isKnown check defaults to letting
  // the user in since nobody not knowing about them is not a sin.
  if (currentURL == NULL) {
    isKnown = TRUE;
  }
  else {
    isKnown = FALSE;
  }

  // Loop through all of the configured authorities
  while (rval == DECLINED && currentURL != NULL) {
    const char* idneeded_value   = (currentURL->idneeded) ? 
      TRUE_STRING : FALSE_STRING;
    const char* aclneeded_value  = (currentURL->aclneeded) ? 
      TRUE_STRING : FALSE_STRING;

    // Tack on a ? if there are no params in the configured URL,
    // or an & if there are.
    const char* initial_delim = (strchr(currentURL->connecturl, '?') == NULL) ? "?" : "&";
                                              
    urlString = apr_pstrcat(r->pool,
                            currentURL->connecturl,
                            initial_delim,
                            PARAM_USERNAME, "=", escapedUserName,
                            "&",
                            PARAM_ID_NEEDED, "=", idneeded_value,
                            "&",
                            PARAM_ACL_NEEDED, "=", aclneeded_value,
                            NULL);
                                       
    // Initialize dataBuffer
    dataBuffer.p = r->pool;
    dataBuffer.first = NULL;
    dataBuffer.last = NULL;

    curl_error_code = curl_easy_setopt(curl_handle, CURLOPT_URL, urlString);
    if (curl_error_code != CURLE_OK) {
      log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_ERR, r, "CURL easy set opt failed: %s", curl_easy_strerror(curl_error_code));
      rval = HTTP_INTERNAL_SERVER_ERROR;
      break;
    }

    log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, r, "About to request %s%s%s from url '%s' (%s)",
               ((currentURL->idneeded) ? "identifier " : ""),
               ((currentURL->idneeded && currentURL->aclneeded)? "and " : ""),
               ((currentURL->aclneeded) ? "acls ":""),
               currentURL->connecturl, urlString);

    curl_error_code = curl_easy_perform(curl_handle);
    if (curl_error_code != CURLE_OK) {
      // failed to connect to authority service; log error and terminate authorization processing
      log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r, "CURL error from url '%s': %s", currentURL->connecturl, curl_easy_strerror(curl_error_code));
      rval = HTTP_INTERNAL_SERVER_ERROR;
      break;
    }
    else {

      // get response code
      long response_code;
      curl_error_code = curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE, &response_code);
      if (curl_error_code != CURLE_OK) {
        log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_ERR, r, "CURL get response code failed");
        rval = HTTP_INTERNAL_SERVER_ERROR;
        break;
      } else if(response_code == 403) {
        // if it's 403, the authority is signaling there's no safe way to reply
        // (e.g., it may not be able to provide the proper deny token), and so
        // we need to also slam the door shut, regardless of whether the infer
        // flag is on or not
        rval = HTTP_UNAUTHORIZED;
        break;
      }

      char* responseLine;

      struct DataIterator di;

      iterator_initialize(&di,&dataBuffer);

      log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, r, "Decoding response");

      while(1) {
        responseLine = iterator_getline(&di,r);
        if(responseLine == NULL) {
          break;
        }

        if (prefix_matches(ID_PREFIX,responseLine)) {
          // Enter string into user table
          apr_table_set(userTable, responseLine + strlen(ID_PREFIX), "");
        }
        else if (prefix_matches(TOKEN_PREFIX,responseLine)) {
          // Enter this string into the group table
          apr_table_set(groupTable, responseLine + strlen(TOKEN_PREFIX), "");
        }
        else if (prefix_matches(UNREACHABLE_PREFIX,responseLine)
                || prefix_matches(UNAUTHORIZED_PREFIX,responseLine)) {
          // note in warning table
          apr_table_set(warningTable, responseLine, "");
          // if we're inferring service authz, deny access
          if(cfg->infer_service_authz) {
            rval = HTTP_UNAUTHORIZED;
            break;
          }
        }
        else if (prefix_matches(NOTFOUND_PREFIX,responseLine)) {
          // note in warning table and do nothing
          apr_table_set(warningTable, responseLine, "");
        }
        else if (prefix_matches(AUTHORIZED_PREFIX,responseLine)) {
          // note that at least one authority has now authorized the user
          isKnown = TRUE;
        }
        else {
          // invalid response from authority service; log error and terminate authorization processing
          log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
                     "Invalid string from authority service '%s'", responseLine);
          rval = HTTP_INTERNAL_SERVER_ERROR;
          break;
        }
      }
    }

    // Free the data buffer
    // no need, since it's in apache pool

    // Free the full url
    // no need, since it's in apache pool

    // Next URL
    currentURL = currentURL->next;
  }

  log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, r, "Completed requests to services");

  curl_easy_cleanup(curl_handle);

  curl_free(escapedUserName);

  // if no one returned authorized and we're inferring service authz from that,
  // deny access now
  if (cfg->infer_service_authz && rval == DECLINED && isKnown == FALSE) {
    curl_slist_free_all(headers);
    return HTTP_UNAUTHORIZED;
  }

  curl_slist_free_all(headers);
  return rval;
}


/*
  Main method that does everything.
*/
static
int
authz_annotate(request_rec *r, const char *connection_user,
               APR_TABLE_T **user_table, APR_TABLE_T **group_table, APR_TABLE_T **warning_table) {

  if (user_table == NULL) {
    log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r, "invalid user_table");
    return HTTP_INTERNAL_SERVER_ERROR;
  }
  if (group_table == NULL) {
    log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r, "invalid group_table");
    return HTTP_INTERNAL_SERVER_ERROR;
  }

  // For the purposes of the java connector, the connection_user is passed in without change  

  //NOTE: do we need to verify that apr_table_make succeeded?
  *user_table = (APR_TABLE_T *)apr_table_make(r->pool, DEFAULT_NUM_USERS);
  *group_table = (APR_TABLE_T *)apr_table_make(r->pool, DEFAULT_NUM_GROUPS);
  *warning_table = (APR_TABLE_T *)apr_table_make(r->pool, DEFAULT_NUM_WARNING);

  // Obtain groups via http
  return authz_annotate_users_and_groups(r,connection_user,*user_table,*group_table,*warning_table);
}


/*
  Convert a table to a header.
*/
static
int
transform_table_to_http_header(APR_TABLE_T* the_table,
                               request_rec *r,
                               const char *header_name,
                               const unsigned int header_name_length,
                               unsigned int *apache_header_size) {
  const APR_ARRAY_HEADER_T *the_array;
  APR_TABLE_ENTRY_T *telts;
  int i;

  the_array = apr_table_elts(the_table);
  telts = (APR_TABLE_ENTRY_T*)the_array->elts;
  
  for(i = 0; i < the_array->nelts; i++) {
    apr_table_add(r->headers_in, header_name, telts[i].key);

    if (apache_header_size != NULL) {
      *apache_header_size += header_name_length + HEADER_SEPARATOR_LEN + strlen(telts[i].key);
    }
  }
  
  return the_array->nelts;
}

#if 0
// List contents of header
static
int
list_stuff(request_rec *r, const char* key, const char* value) {
  if (strcmp(key,USER_HEADER_KEY) == 0 || strcmp(key,GROUP_HEADER_KEY) == 0) {
    log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, r,
               "Found key = %s value = %s",key,value);
  }
  return 0;
}
#endif


/*
  Clean headers handler.  This will be done regardless of the authorization configuration.
*/
static
int
authz_clean_headers_handler(request_rec *r) {  
  struct Config* cfg;

  cfg = (struct Config*) ap_get_module_config(r->per_dir_config, &authz_annotate_module);

  /* Skip processing if we're not active. */
  if( cfg->activated == 0 ) {
    return DECLINED;
  }

  /* Get rid of any passed in authz headers to prevent spoofing. */
  apr_table_unset(r->headers_in, USER_NAME_HEADER_KEY);
  apr_table_unset(r->headers_in, USER_HEADER_KEY);
  apr_table_unset(r->headers_in, GROUP_HEADER_KEY);

  return OK;
}


static
void
authz_annotate_add_username_header(request_rec *r) {
  // if there is a valid username
  if (APACHE_REQUEST_USER != NULL) {
    // escape the username to eliminate leading or trailing spaces
    // which are dropped in http headers
    char *escaped_username = ap_escape_uri(r->pool, APACHE_REQUEST_USER);
    
    // stuff username into headers for webui (tomcat)
    apr_table_add(r->headers_in, USER_NAME_HEADER_KEY, escaped_username);
  }
}

/*
  This is the content handler
*/
static
int
authz_annotate_authorization_handler(request_rec *r) {  
  struct Config* cfg;
  int authz_annotate_result;
  APR_TABLE_T *user_table;
  APR_TABLE_T *group_table;
  APR_TABLE_T *warning_table;

  cfg = (struct Config*) ap_get_module_config(r->per_dir_config, &authz_annotate_module);

  /* Everything OK by default if we're not even active. */
  if( cfg->activated == 0 ) {
    return DECLINED;
  }

  /* We must have a user to authorize against */
  if (APACHE_REQUEST_USER == NULL) {
    return HTTP_UNAUTHORIZED;
  }

  /* if this is a subrequest, we've already done our annotation work so DECLINE to do anything with it */
  if (! ap_is_initial_req(r)) {
    return DECLINED;
  }
  
  log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r,
             "Authorization request for user '%s'",
             APACHE_REQUEST_USER);

  // add username header
  authz_annotate_add_username_header(r);
  
  authz_annotate_result = authz_annotate(r, APACHE_REQUEST_USER, &user_table, &group_table, &warning_table);

  if (authz_annotate_result == DECLINED) {
    unsigned int apache_header_size = 0;
    unsigned int number_of_users_added = 0;
    unsigned int number_of_groups_added = 0;
    unsigned int number_of_warning_added = 0;
    
    number_of_users_added = transform_table_to_http_header(user_table,
                                                           r,
                                                           USER_HEADER_KEY,
                                                           STATIC_STRLEN(USER_HEADER_KEY),
                                                           &apache_header_size);
    
    number_of_groups_added = transform_table_to_http_header(group_table,
                                                            r,
                                                            GROUP_HEADER_KEY,
                                                            STATIC_STRLEN(GROUP_HEADER_KEY),
                                                            &apache_header_size);

    if(!apr_is_empty_table(warning_table)) {
      number_of_warning_added = transform_table_to_http_header(warning_table,
                                                               r,
                                                               WARNING_HEADER_KEY,
                                                               STATIC_STRLEN(WARNING_HEADER_KEY),
                                                               &apache_header_size);
    }
    
    log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r,
               "users(%u) groups(%u) warning(%u) header size: %u",
               number_of_users_added,
               number_of_groups_added,
               number_of_warning_added,
               apache_header_size);
  }
  
  return authz_annotate_result;
}

/*
  Write a table to the request header.
*/
static
void
print_table_to_client(APR_TABLE_T* the_table,
                      request_rec *r,
                      const char *header_name) {
  const APR_ARRAY_HEADER_T *the_array;
  APR_TABLE_ENTRY_T *telts;
  int i;

  the_array = apr_table_elts(the_table);
  telts = (APR_TABLE_ENTRY_T*)the_array->elts;
  
  for(i = 0; i < the_array->nelts; i++) {
    ap_rprintf(r, "%s: %s\n", header_name, telts[i].key);
  }
}

static
int
authz_annotate_content_handler(request_rec *r) {  
  APR_TABLE_T *user_table;
  APR_TABLE_T *group_table;
  APR_TABLE_T *warning_table;
  int authz_annotate_result;
  const char *user_name;

#ifdef STANDARD20_MODULE_STUFF
  if (!r->handler || strcmp(r->handler, "authz-annotate")) {
    return DECLINED;
  }
#endif
  
  user_name = apr_table_get(r->headers_in, FAKE_USER_HEADER_KEY);
  if(user_name == NULL) {
    return HTTP_INTERNAL_SERVER_ERROR;
  }
  authz_annotate_result = authz_annotate(r, user_name, &user_table, &group_table, &warning_table);

#ifdef STANDARD20_MODULE_STUFF
  ap_set_content_type(r, "text/plain");
#else
  r->content_type = "text/plain";
  ap_send_http_header(r);
#endif

  // TODO: for consistency we should REALLY send the USER_NAME_HEADER here as well
  
  if (authz_annotate_result == DECLINED) {
    print_table_to_client(user_table, r, USER_HEADER_KEY);
    print_table_to_client(group_table, r, GROUP_HEADER_KEY);
    print_table_to_client(warning_table, r, WARNING_HEADER_KEY);
  }
  else {
    ap_rprintf(r, "ERROR: internal failure (see /var/log/metacarta/error.log) %d\n", authz_annotate_result);
  }
  // MUST return ok, otherwise content will come from elsewhere (and get errors)
  return OK;
}


#ifdef STANDARD20_MODULE_STUFF
#define command(name, func, var, type, usage)  \
  AP_INIT_ ## type (name, (void*) func, NULL, OR_AUTHCFG | RSRC_CONF, usage)
#else
#define command(name, func, var, type, usage)  \
  { name, func, NULL, OR_AUTHCFG | RSRC_CONF, type, usage }
#endif

/* Configuration command description */
static const command_rec authz_annotate_cmds[] = {
  command("AuthzAnnotateEnable", activation_flag_cmd, NULL, FLAG,"Toggle state of authority feature"),
  command("AuthzAnnotateInferServiceAuthz",infer_service_authz_cmd, NULL, FLAG,"Toggle state of authority feature"),
  command("AuthzAnnotateAuthority", connecturl_noid_yesacl_cmd, NULL, TAKE1, "Protocol, host, port, and service to connect to"),
  command("AuthzAnnotateACLAuthority", connecturl_noid_yesacl_cmd, NULL, TAKE1, "Protocol, host, port, and service to connect to"),
  command("AuthzAnnotateIDAuthority", connecturl_yesid_noacl_cmd, NULL, TAKE1, "Protocol, host, port, and service to connect to"),
  command("AuthzAnnotateIDACLAuthority", connecturl_yesid_yesacl_cmd, NULL, TAKE1, "Protocol, host, port, and service to connect to"),
  {NULL}
};



#ifdef STANDARD20_MODULE_STUFF

static
apr_status_t
authz_annotate_child_cleanup(void *data) {
  curl_global_cleanup();
  return APR_SUCCESS;
}

/* Child initialization. */
static
void
authz_annotate_child_init(APR_POOL_T *p, server_rec *s) {
  CURLcode curl_error;

  curl_error = curl_global_init(CURL_GLOBAL_NOTHING);
  if (curl_error != CURLE_OK) {
    // Write an error to the log
    ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, 0, s, "Couldn't initialize CURL: %d %s", curl_error, curl_easy_strerror(curl_error));
    curl_init_failed = 1;
  }
  else {
    curl_init_failed = 0;
  }
  
  apr_pool_cleanup_register(p, s, authz_annotate_child_cleanup, authz_annotate_child_cleanup);
}


static
int
authz_annotate_init_handler(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) {
  ap_add_version_component(p, MODULE_NAME "/" MODULE_VERSION); 
  return OK;
}


static
void
authz_annotate_register_hooks(apr_pool_t *p) {
  ap_log_perror(APLOG_MARK, APLOG_DEBUG|APLOG_ERR, 0, p, "HERE I AM\n");

  ap_hook_post_config(authz_annotate_init_handler, NULL, NULL, APR_HOOK_MIDDLE);
  ap_hook_child_init(authz_annotate_child_init, NULL, NULL, APR_HOOK_MIDDLE);
  ap_hook_header_parser(authz_clean_headers_handler, NULL, NULL, APR_HOOK_MIDDLE);
  ap_hook_auth_checker(authz_annotate_authorization_handler, NULL, NULL, APR_HOOK_FIRST);
  ap_hook_handler(authz_annotate_content_handler, NULL, NULL, APR_HOOK_MIDDLE);
}

module AP_MODULE_DECLARE_DATA authz_annotate_module = {
   STANDARD20_MODULE_STUFF,
   create_config,                 /* create per-dir    conf structures  */
   merge_config,                  /* merge  per-dir    conf structures  */
   NULL,                          /* create per-server conf structures  */
   NULL,                          /* merge  per-server conf structures  */
   authz_annotate_cmds,           /* table of configuration directives  */
   authz_annotate_register_hooks  /* register hooks                     */
};

#else

/* Child initialization. */
static
void
authz_annotate_child_init(server_rec *s, APR_POOL_T *p) {
  CURLcode curl_error;

  curl_error = curl_global_init(CURL_GLOBAL_NOTHING);
  if (curl_error != CURLE_OK) {
    // Write an error to the log
    ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, s, "Couldn't initialize CURL: %d %s", curl_error, curl_easy_strerror(curl_error));
    curl_init_failed = 1;
  }
  else {
    curl_init_failed = 0;
  }
}


/* Child exit.  */
static
void
authz_annotate_child_exit(server_rec *s, APR_POOL_T *p) {
  curl_global_cleanup();
}

/* content handlers */
static handler_rec authz_annotate_handlers[] = {
  { "authz-annotate", authz_annotate_content_handler },
  { NULL }
};

/* Dispatch list for API hooks */
module MODULE_VAR_EXPORT authz_annotate_module = {
  STANDARD_MODULE_STUFF,
  NULL,                         /* module initializer                  */
  create_config,                /* create per-dir    config structures */
  merge_config,                 /* merge  per-dir    config structures */
  NULL,                         /* create per-server config structures */
  NULL,                         /* merge  per-server config structures */
  authz_annotate_cmds,          /* table of config file commands       */
  authz_annotate_handlers,      /* [#8] MIME-typed-dispatched handlers */
  NULL,                         /* [#1] URI to filename translation    */
  NULL,                         /* [#4] validate user id from request  */
  authz_annotate_authorization_handler, /* [#5] check if the user is ok _here_ */
  NULL,                         /* [#3] check access by host address   */
  NULL,                         /* [#6] determine MIME type            */
  NULL,                         /* [#7] pre-run fixups                 */
  NULL,                         /* [#9] log a transaction              */
  authz_clean_headers_handler,  /* [#2] header parser                  */
  authz_annotate_child_init,    /* child_init                          */
  authz_annotate_child_exit,    /* child_exit                          */
  NULL                          /* [#0] post read-request              */
#ifdef EAPI
  ,NULL,                        /* EAPI: add_module                    */
  NULL,                         /* EAPI: remove_module                 */
  NULL,                         /* EAPI: rewrite_command               */
  NULL                          /* EAPI: new_connection                */
#endif
};


#endif
