/** 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"); }
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; }
static verify_success signatura_verify_request(request_rec *request) { apr_table_t *params; ap_args_to_table(request, ¶ms); 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); }
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; }
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; }
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; }
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, ¶ms, 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; }
/* * 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; }