Example #1
0
/**
var get: Hash[String, Tainted[String]]

This contains key+value pairs that were sent to the server as GET variables.
Any pair that has a key or a value that is not valid utf-8 will not be present.
*/
static lily_value *load_var_get(lily_options *options, uint16_t *unused)
{
    apr_table_t *http_get_args;
    ap_args_to_table((request_rec *)options->data, &http_get_args);

    return bind_table_as(options, http_get_args, "get");
}
Example #2
0
int webgfarm_api_v1(request_rec *r) {
    apr_table_t *table;
    const char *rename;

    int ret = HTTP_INTERNAL_SERVER_ERROR;

    ap_args_to_table(r, &table);
    char *filepath = webgfarm_api_v1_getfilepath(r);
    switch (r->method_number) {
        case M_GET:
            // return payload and metadata
            if (isdir(filepath)) {
                ret = webgfarm_api_v1_read_dir(r);
            } else {
                ret = webgfarm_api_v1_read_file(r);
            }
            break;
        case M_PUT:
            rename = apr_table_get(table, "rename");
            if (rename) {
            } else {
                // overwrite the file
                if (isdir(filepath)) {
                    ret = webgfarm_api_v1_create_dir(r);
                } else {
                    ret = webgfarm_api_v1_write_to_file(r);
                }
            }
            break;
        case M_POST:
            // append the file
            ret = webgfarm_api_v1_write_to_file(r);
            break;
        case M_DELETE:
            // remove the file
            ret = webgfarm_api_v1_delete_file(r);
            break;
    }

    //    }
    return ret;
}
Params * getGetParams(request_rec *r, apr_off_t * getSize){
	Params * params;
	apr_table_t *GET;	
	ap_args_to_table(r, &GET);
	
	const apr_array_header_t *parmsArray = apr_table_elts(GET);
	const apr_table_entry_t * getParms = (apr_table_entry_t*)parmsArray->elts;
	
	*getSize = parmsArray->nelts;
	
	params = apr_pcalloc(r->pool, sizeof(Params) * (*getSize + 1));
	int i = 0;
	for (i = 0; i < *getSize; i++) {
		params[i].key = getParms[i].key;
		params[i].val = getParms[i].val;
		params[i].length = strlen(params[i].val);
		//ap_rprintf(r,"key : val : len: is %s : %s : %d ===", params[i].key, params[i].val, params[i].length);
	}
	return params;
}
Example #4
0
static verify_success signatura_verify_request(request_rec *request)
{
  apr_table_t *params;
  ap_args_to_table(request, &params);

  const char *key_id = apr_table_get(params, "key_id");
  const char *expires = apr_table_get(params, "expires");
  const char *signature = apr_table_get(params, "signature");

  if (!key_id) {
    signatura_write_error_message(request, "Please supply a `key_id' query parameter.");
    return S_FAILED;
  }

  if (strlen(key_id) > 512) {
    signatura_write_error_message(request, "Maximum size for the `key_id' query parameter is 512 bytes.");
    return S_FAILED;
  }

  if (!expires) {
    signatura_write_error_message(request, "Please supply an `expires' query parameter.");
    return S_FAILED;
  }

  if (strlen(expires) > 512) {
    signatura_write_error_message(request, "Maximum size for the `expires' query parameter is 512 bytes.");
    return S_FAILED;
  }

  if (!signature) {
    signatura_write_error_message(request, "Please supply a `signature' query parameter.");
    return S_FAILED;
  }

  if (strlen(signature) > 80) {
    signatura_write_error_message(request, "Maximum size for the `signature' query parameter is 80 bytes.");
    return S_FAILED;
  }

  return signatura_request_valid(request, key_id, expires, signature);
}
Example #5
0
static int apache_bind_server(lily_parse_state *parser, request_rec *r)
{
    int ret = 1;
    lily_symtab *symtab = parser->symtab;
    lily_class *package_cls = lily_class_by_id(symtab, SYM_CLASS_PACKAGE);
    lily_sig *package_sig = lily_try_sig_for_class(symtab, package_cls);
    lily_var *bound_var = lily_try_new_var(symtab, package_sig, "server", 0);
    if (bound_var) {
        lily_var *save_top = symtab->var_top;
        int save_spot = symtab->next_register_spot;
        int count = 0;

        ap_add_cgi_vars(r);
        ap_add_common_vars(r);
        bind_table_as(&count, parser, r, r->subprocess_env, "env");

        apr_table_t *http_get_args;
        ap_args_to_table(r, &http_get_args);
        bind_table_as(&count, parser, r, http_get_args, "get");

        bind_post(&count, parser, r);

        bind_httpmethod(&count, parser, r);

        if (count != -1) {
            int ok = 1;
            make_package(&ok, parser, bound_var, count, save_spot, save_top);
            if (ok == 0)
                ret = 0;
        }
        else
            ret = 0;
    }
    else
        ret = 0;

    return ret;
}
Example #6
0
static int mod_handler_execute(request_rec *r) {

	if (!config.secretKey) {
		if (config.debugLevel >= 1) {
			ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r->server, "No such secretKey set");
		}
		return DECLINED;
	}

	if (!config.iv) {
		if (config.debugLevel >= 1) {
			ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r->server, "No such IV set");
		}
		return DECLINED;
	}

	if (!config.algorithm) {
		if (config.debugLevel >= 1) {
			ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r->server, "No such algorithm set");
		}
		return DECLINED;
	}

	if (!strcasecmp(config.algorithm, "aes") && !strcasecmp(config.algorithm, "desede")) {
		if (config.debugLevel >= 2) {
			ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r->server, "No such algorithm %s exists", config.algorithm);
		}
		return DECLINED;
	}

	apr_table_t*GET;
	ap_args_to_table(r, &GET);

	const char* tokenParam = config.tokenParam == 0 ? "token" : config.tokenParam;
	const char *token = getParam(GET, tokenParam, "");
	size_t tokenLength = strlen((char*)token);

	if (tokenLength == 0) {
		if (config.debugLevel >= 2) {
			ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r->server, "No such token passed");
		}
		return DECLINED;
	}

	const unsigned char* key = config.secretKey;
	const unsigned char* ivEncoded = config.iv;
	int ivEncodedLen = strlen((char*) config.iv);
	long keylength = strlen((char*) config.secretKey);
	unsigned char* ivDecoded = 0;
	int ivDecodedLen = 0;
	unsigned char* dataDecoded = 0;
	int dataDecodedLen = 0;
	cryptoc_data* deciphereddata = 0;

	if (config.debugLevel >= 3) {
		ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r->server, "Process started");
	}

	deciphereddata = (cryptoc_data*) malloc(sizeof(cryptoc_data));

	if (!deciphereddata) {
		if (config.debugLevel >= 2) {
			ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r->server, "Could not allocate memory for decrypt data");
		}
		_free_crypto_data(deciphereddata, dataDecoded, ivDecoded);
		return DECLINED;
	}

	dataDecoded = (unsigned char*) malloc(sizeof(unsigned char) * tokenLength);

	if (!dataDecoded) {
		if (config.debugLevel >= 2) {
			ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r->server, "Could not allocate memory for decoded data");
		}
		_free_crypto_data(deciphereddata, dataDecoded, ivDecoded);
		return DECLINED;
	}

	dataDecodedLen = cryptoc_base64_decode(token, tokenLength, dataDecoded);

	if (!dataDecodedLen || !dataDecoded) {
		if (config.debugLevel >= 2) {
			ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r->server, "Could not base64 decode data");
		}
		_free_crypto_data(deciphereddata, dataDecoded, ivDecoded);
		return DECLINED;
	}

	if (config.debugLevel >= 3) {
		ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, 0, r->server, "Data decoded successfully");
	}

	ivDecoded = (unsigned char*) malloc(sizeof(unsigned char) * strlen((const char*)ivEncoded));

	if (!ivDecoded) {
		if (config.debugLevel >= 2) {
			ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r->server, "Could not allocate memory for IV");
		}
		_free_crypto_data(deciphereddata, dataDecoded, ivDecoded);
		return DECLINED;
	}

	ivDecodedLen = cryptoc_base64_decode(ivEncoded, strlen((const char*)ivEncoded), ivDecoded);

	if (!ivDecodedLen || !ivDecoded) {
		if (config.debugLevel >= 2) {
			ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r->server, "Could not base64 decode IV");
		}
		_free_crypto_data(deciphereddata, dataDecoded, ivDecoded);
		return DECLINED;
	}

	if (config.debugLevel >= 3) {
		ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, 0, r->server, "IV decoded successfully");
	}

	*deciphereddata = cryptoc_decrypt_iv(CRYPTOC_DES_EDE3_CBC, key, keylength, ivDecoded, ivDecodedLen, dataDecoded, dataDecodedLen);

	if (!deciphereddata || deciphereddata->error) {
		if (deciphereddata) {
			if (config.debugLevel >= 2) {
				ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r->server, "Deciphering error: %s", deciphereddata->errorMessage);
			}
		} else {
			ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r->server, "Deciphering error: unknown error");
		}
		_free_crypto_data(deciphereddata, dataDecoded, ivDecoded);
		return DECLINED;
	}

	if (config.debugLevel >= 3) {
		ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, 0, r->server, "Data decrypted successfully");
	}

	unsigned char* finalData = 0;
	finalData = (unsigned char*) malloc(sizeof(unsigned char) * deciphereddata->length + 1);

	if (!finalData){
		if (config.debugLevel >= 2) {
			ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r->server, "Could not allocate final data");
		}
		return DECLINED;
	}

	strncpy(finalData, deciphereddata->data, deciphereddata->length);
	finalData[deciphereddata->length + 1] = '\0';

	if (config.debugLevel >= 2) {
		ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, 0, r->server, "Final data copied successfully. Decrypted data: %s", finalData);
	}

	_free_crypto_data(deciphereddata, dataDecoded, ivDecoded);

	if (config.debugLevel >= 3) {
		ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r->server, "Process finished");
	}

	return OK;
}
Example #7
0
static int mod_handler_debug(request_rec *r) {

	// The first thing we will do is write a simple "Hello, world!" back to the client.
	ap_set_content_type(r, "text/html"); /* force a raw text output */
	ap_rputs("Hello, world!<br/>\n", r);

	if (config.secretKey) {
		ap_rprintf(r, "SecretKey is: %s<br/>\n", config.secretKey);
	}

	if (config.iv) {
		ap_rprintf(r, "IV is: %s<br/>\n", config.iv);
	}

	if (config.tokenParam) {
		ap_rprintf(r, "TokenParam is: %s<br/>\n", config.tokenParam);
	}

	if (config.algorithm) {
		ap_rprintf(r, "Algorithm is: %s<br/>\n", config.algorithm);
	}

	ap_rprintf(r, "parsed_uri.path: %s<br/>\n", r->parsed_uri.path);
	ap_rprintf(r, "parsed_uri.fragment: %s<br/>\n", r->parsed_uri.fragment);
	ap_rprintf(r, "parsed_uri.hostinfo: %s<br/>\n", r->parsed_uri.hostinfo);
	ap_rprintf(r, "parsed_uri.query: %s<br/>\n", r->parsed_uri.query);
	ap_rprintf(r, "parsed_uri.hostname: %s<br/>\n", r->parsed_uri.hostname);
	ap_rprintf(r, "parsed_uri.user: %s<br/>\n", r->parsed_uri.user);
	ap_rprintf(r, "parsed_uri.scheme: %s<br/>\n", r->parsed_uri.scheme);
	ap_rprintf(r, "request: %s<br/>\n", r->path_info);
	ap_rprintf(r, "filename: %s<br/>\n", r->filename);

	apr_table_t*GET;
	ap_args_to_table(r, &GET);

	apr_array_header_t*POST;
	ap_parse_form_data(r, NULL, &POST, -1, 8192);

	if (!config.secretKey) {
		ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r->server, "No such secretKey set");
		return DECLINED;
	}

	if (!config.iv) {
		ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r->server, "No such IV set");
		return DECLINED;
	}

	if (!config.algorithm) {
		ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r->server, "No such algorithm set");
		return DECLINED;
	}

	/* Get the "digest" key from the query string, if any. */
	// use const
	unsigned char *plain = (unsigned char*) getParam(GET, "plain", "The fox jumped over the lazy dog");

	/* Get the "digest" key from the query string, if any. */
	// use const
	unsigned char *cipherparam = (unsigned char*) getParam(GET, "cipher", "");

	// use const
	const unsigned char *iv = (unsigned char*) "aefpojaefojaepfojaepaoejfapeojfaeopjaej";
	long ivlength = strlen((char*)iv);

	/* Get the "digest" key from the query string, if any. */
	// use const
	unsigned char *key = (unsigned char*) getParam(GET, "key", "The fox jumped over the lazy dog");
	long keylength = strlen((char*)key);

	if (strlen((char*)key) > 0) {

		if (strlen((char*)plain) > 0) {
			cryptoc_data ciphereddata = cryptoc_encrypt_iv(CRYPTOC_AES_192_CBC, key, keylength, iv, ivlength, plain, strlen((char*)plain));

			if (!ciphereddata.error) {

				ap_rprintf(r, "Ciphered data: %s \n<br />", ciphereddata.data);
				ap_rputs("Ciphered HEX data: ", r);
				ap_rprintf_hex(r, ciphereddata.data, ciphereddata.length);
				ap_rputs("\n<br />", r);

				cryptoc_data deciphereddata = cryptoc_decrypt_iv(CRYPTOC_AES_192_CBC, key, keylength, iv, ivlength, ciphereddata.data, ciphereddata.length);

				if (!deciphereddata.error) {
					deciphereddata.data[deciphereddata.length] = '\0';

					ap_rprintf(r, "DECiphered data: %s <br />", deciphereddata.data);
				} else {
					ap_rprintf(r, "Error!! %s", deciphereddata.errorMessage);
				}
			} else {
				ap_rprintf(r, "Error!! %s", ciphereddata.errorMessage);
			}
		}

		if (strlen((char*)cipherparam) > 0) {

			unsigned char* cipher = ap_hex_to_char(r, cipherparam, strlen((char*)cipherparam));

			/* The following line just prints a message to the errorlog */
			//ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, 0, r->server, "Cipher is %s / %s / %d", cipher, (cipherparam), strlen((char*)cipherparam));

			cryptoc_data deciphereddata = cryptoc_decrypt_iv(CRYPTOC_AES_192_CBC, key, keylength, iv, ivlength, cipher, strlen((char*)cipher));

			if (!deciphereddata.error) {
				deciphereddata.data[deciphereddata.length] = '\0';
				ap_rprintf(r, "DECiphered data: %s <br />", deciphereddata.data);
			} else {
				ap_rprintf(r, "Error!! %s", deciphereddata.errorMessage);
			}
		}

	} else {

		/* The following line just prints a message to the errorlog */
		//ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, 0, r->server, "mod_token_auth: key is empty. %s %s", plain, cipherparam);
	}

	return OK;
}
Example #8
0
static int pgasp_handler (request_rec * r)
{
   char cursor_string[256];
   pgasp_config* config = (pgasp_config*) ap_get_module_config(r->server->module_config, &pgasp_module ) ;
   pgasp_dir_config* dir_config = (pgasp_dir_config*) ap_get_module_config(r->per_dir_config, &pgasp_module ) ;
   apr_table_t * GET = NULL, *GETargs = NULL;
   apr_array_header_t * POST;
   PGconn * pgc;
   PGresult * pgr;
   int i, j, allowed_to_serve, filename_length = 0;
   int field_count, tuple_count;
   char * requested_file;
   char *basename;
   params_t params;

   /* PQexecParams doesn't seem to like zero-length strings, so we feed it a dummy */
   const char * dummy_get = "nothing";
   const char * dummy_user = "******";

   const char * cursor_values[2] = { r -> args ? apr_pstrdup(r->pool, r -> args) : dummy_get, r->user ? r->user : dummy_user };
   int cursor_value_lengths[2] = { strlen(cursor_values[0]), strlen(cursor_values[1]) };
   int cursor_value_formats[2] = { 0, 0 };

   if (!r -> handler || strcmp (r -> handler, "pgasp-handler") ) return DECLINED;
   if (!r -> method || (strcmp (r -> method, "GET") && strcmp (r -> method, "POST")) ) return DECLINED;

   if (config->is_enabled != true) return OK; /* pretending we have responded, may return DECLINED in the future */

   requested_file = apr_pstrdup (r -> pool, r -> path_info /*filename*/);
   i = strlen(requested_file) - 1;

   while (i > 0)
   {
     if (requested_file[i] == '.') filename_length = i;
     if (requested_file[i] == '/') break;
     i--;
   }

   if (i >= 0) {
     requested_file += i+1; /* now pointing to foo.pgasp instead of /var/www/.../foo.pgasp */
     if (filename_length > i) filename_length -= i+1;
   }

   allowed_to_serve = false;

   for (i = 0; i < config->allowed_count; i++)
   {
      if (!strcmp(config->allowed[i], requested_file))
      {
         allowed_to_serve = true;
         break;
      }
   }
   if (config->allowed_count == 0) allowed_to_serve = true;

   if (!allowed_to_serve)
   {
      ap_set_content_type(r, "text/plain");
      ap_rprintf(r, "Hello there\nThis is PGASP\nEnabled: %s\n", config->is_enabled ? "On" : "Off");
      ap_rprintf(r, "Requested: %s\n", requested_file);
      ap_rprintf(r, "Allowed: %s\n", allowed_to_serve ? "Yes" : "No");

      return OK; /* pretending we have served the file, may return HTTP_FORDIDDEN in the future */
   }

   if (filename_length == 0) {
     basename = requested_file;
   } else {
     basename = apr_pstrndup(r->pool, requested_file, filename_length);
   }

   ap_args_to_table(r, &GETargs);
   if (OK != ap_parse_form_data(r, NULL, &POST, -1, (~((apr_size_t)0)))) {
     __(r->server, " ** ap_parse_form_data is NOT OK");
   }
   GET = (NULL == GET) ? GETargs : apr_table_overlay(r->pool, GETargs, GET);

   // move all POST parameters into GET table
   {
     ap_form_pair_t *pair;
     char *buffer;
     apr_off_t len;
     apr_size_t size;
     while (NULL != (pair = apr_array_pop(POST))) {
       apr_brigade_length(pair->value, 1, &len);
       size = (apr_size_t) len;
       buffer = apr_palloc(r->pool, size + 1);
       apr_brigade_flatten(pair->value, buffer, &size);
       buffer[len] = 0;
       apr_table_setn(GET, apr_pstrdup(r->pool, pair->name), buffer); //should name and value be ap_unescape_url() -ed?
       //       __(r->server, "POST[%s]: %s", pair->name, buffer);
     }
   }

   params.r = r;
   params.args = NULL;
   apr_table_do(tab_args, &params, GET, NULL);
   params.args = apr_pstrcat(r->pool, "&", params.args, "&", NULL);

   cursor_values[0] = params.args;
   cursor_value_lengths[0] = strlen(cursor_values[0]);

   /* set response content type according to configuration or to default value */
   ap_set_content_type(r, dir_config->content_type_set ? dir_config->content_type : "text/html");

   /* now connecting to Postgres, getting function output, and printing it */

   pgc = pgasp_pool_open (r->server);

   if (PQstatus(pgc) != CONNECTION_OK)
   {
      spit_pg_error ("connect");
      pgasp_pool_close(r->server, pgc);
      return OK;
   }

   /* removing extention (.pgasp or other) from file name, and adding "f_" for function name, i.e. foo.pgasp becomes psp_foo() */
   snprintf(cursor_string,
	    sizeof(cursor_string),
	    "select * from f_%s($1::varchar)",
	    basename);

   /* passing GET as first (and only) parameter */
   if (0 == PQsendQueryParams (pgc, cursor_string, 1, NULL, cursor_values, cursor_value_lengths, cursor_value_formats, 0)) {
      spit_pg_error ("sending async query with params");
      return clean_up_connection(r->server);
   }

   if (0 == PQsetSingleRowMode(pgc)) {
     ap_log_error(APLOG_MARK, APLOG_WARNING, 0, r->server, "can not fall into single raw mode to fetch data");
   }

   while (NULL != (pgr = PQgetResult(pgc))) {

     if (PQresultStatus(pgr) != PGRES_TUPLES_OK && PQresultStatus(pgr) != PGRES_SINGLE_TUPLE) {
       spit_pg_error ("fetch data");
       return clean_up_connection(r->server);
     }

     /* the following counts and for-loop may seem excessive as it's just 1 row/1 field, but might need it in the future */

     field_count = PQnfields(pgr);
     tuple_count = PQntuples(pgr);

     for (i = 0; i < tuple_count; i++)
       {
	 for (j = 0; j < field_count; j++) ap_rprintf(r, "%s", PQgetvalue(pgr, i, j));
	 ap_rprintf(r, "\n");
       }
     PQclear (pgr);
   }
   pgasp_pool_close(r->server, pgc);

   return OK;
}
Example #9
0
/*
 * this routine gives our module another chance to examine the request
 * headers and to take special action. This is the first phase whose
 * hooks' configuration directives can appear inside the <Directory>
 * and similar sections, because at this stage the URI has been mapped
 * to the filename. For example this phase can be used to block evil
 * clients, while little resources were wasted on these.
 *
 * This is a RUN_ALL hook.
 */
static int header_parser(request_rec *r) {
    // Get the module configuration
    dir_config_t *dcfg = (dir_config_t *) ap_get_module_config(r->per_dir_config, &defender_module);

    // Stop if Defender not enabled
    if (!dcfg->defender)
        return DECLINED;

    RuntimeScanner *scanner = new RuntimeScanner(*dcfg->parser);

    // Register a C function to delete scanner at the end of the request cycle
    apr_pool_cleanup_register(r->pool, (void *) scanner, defender_delete_runtimescanner_object,
                              apr_pool_cleanup_null);

    // Reserve a temporary memory block from the request pool to store data between hooks
    defender_config_t *pDefenderConfig = (defender_config_t *) apr_palloc(r->pool, sizeof(defender_config_t));

    // Remember our application pointer for future calls
    pDefenderConfig->vpRuntimeScanner = scanner;

    // Register our config data structure for our module for retrieval later as required
    ap_set_module_config(r->request_config, &defender_module, (void *) pDefenderConfig);

    // Set method
    if (r->method_number == M_GET)
        scanner->method = METHOD_GET;
    else if (r->method_number == M_POST)
        scanner->method = METHOD_POST;
    else if (r->method_number == M_PUT)
        scanner->method = METHOD_PUT;

    // Set logger info
    scanner->pid = getpid();
    apr_os_thread_t tid = apr_os_thread_current();
    unsigned int pid_buffer_len = 16;
    char pid_buffer[pid_buffer_len];
    apr_snprintf(pid_buffer, pid_buffer_len, "%pT", &tid);
    scanner->threadId = std::string(pid_buffer);
    scanner->connectionId = r->connection->id;
    scanner->clientIp = r->useragent_ip;
    scanner->requestedHost = r->hostname;
    scanner->serverHostname = r->server->server_hostname;
    scanner->fullUri = r->unparsed_uri;
    scanner->protocol = r->protocol;
    ap_version_t vers;
    ap_get_server_revision(&vers);
    scanner->softwareVersion = std::to_string(vers.major) + "." + std::to_string(vers.minor) + "." +
                               std::to_string(vers.patch);
    scanner->logLevel = static_cast<LOG_LVL>(r->log->level);
    if (scanner->logLevel >= APLOG_DEBUG)
        scanner->logLevel = LOG_LVL_DEBUG;
    scanner->writeLogFn = write_log;
    scanner->errorLogFile = r->server->error_log;
    scanner->learningLogFile = dcfg->matchlog_file;
    scanner->learningJSONLogFile = dcfg->jsonmatchlog_file;
    scanner->learning = dcfg->learning;
    scanner->extensiveLearning = dcfg->extensive;

    // Set runtime modifiers
    scanner->libinjSQL = dcfg->libinjection_sql;
    scanner->libinjXSS = dcfg->libinjection_xss;
    scanner->bodyLimit = dcfg->requestBodyLimit;

    // Set the uri path
    scanner->setUri(r->parsed_uri.path);

    // Pass every HTTP header received
    const apr_array_header_t *headerFields = apr_table_elts(r->headers_in);
    apr_table_entry_t *headerEntry = (apr_table_entry_t *) headerFields->elts;
    for (int i = 0; i < headerFields->nelts; i++)
        scanner->addHeader(headerEntry[i].key, headerEntry[i].val);

    // Pass GET parameters
    apr_table_t *getTable = NULL;
    ap_args_to_table(r, &getTable);
    const apr_array_header_t *getParams = apr_table_elts(getTable);
    apr_table_entry_t *getParam = (apr_table_entry_t *) getParams->elts;
    for (int i = 0; i < getParams->nelts; i++)
        scanner->addGETParameter(getParam[i].key, getParam[i].val);

    // Run scanner
    int ret = scanner->processHeaders();

    if (dcfg->useenv)
        ret = pass_in_env(r, scanner);

    return ret;
}