summaryrefslogtreecommitdiff
path: root/school/node_modules/node-forge/mod_fsp/mod_fsp.c
diff options
context:
space:
mode:
Diffstat (limited to 'school/node_modules/node-forge/mod_fsp/mod_fsp.c')
-rw-r--r--school/node_modules/node-forge/mod_fsp/mod_fsp.c415
1 files changed, 0 insertions, 415 deletions
diff --git a/school/node_modules/node-forge/mod_fsp/mod_fsp.c b/school/node_modules/node-forge/mod_fsp/mod_fsp.c
deleted file mode 100644
index 8beb824..0000000
--- a/school/node_modules/node-forge/mod_fsp/mod_fsp.c
+++ /dev/null
@@ -1,415 +0,0 @@
-/**
- * Flash Socket Policy Apache Module.
- *
- * This module provides a flash socket policy file on the same port that
- * serves HTTP on Apache. This can help simplify setting up a server that
- * supports cross-domain communication with flash.
- *
- * Quick note about Apache memory handling: Data is allocated from pools and
- * is not manually returned to those pools. The pools are typically considered
- * short-lived and will be cleaned up automatically by Apache.
- *
- * @author Dave Longley
- *
- * Copyright (c) 2010 Digital Bazaar, Inc. All rights reserved.
- */
-#include "httpd.h"
-#include "http_config.h"
-#include "http_core.h"
-
-#include "ap_compat.h"
-
-#include <string.h>
-
-// length of a policy file request
-#define PFR_LENGTH 23
-
-// declare main module
-module AP_MODULE_DECLARE_DATA fsp_module;
-
-// configuration for the module
-typedef struct fsp_config
-{
- // the cross-domain policy to serve
- char* policy;
- apr_size_t policy_length;
-} fsp_config;
-
-// filter state for keeping track of detected policy file requests
-typedef struct filter_state
-{
- fsp_config* cfg;
- int checked;
- int found;
-} filter_state;
-
-// for registering hooks, filters, etc.
-static void fsp_register_hooks(apr_pool_t *p);
-static int fsp_pre_connection(conn_rec *c, void *csd);
-
-// filter handler declarations
-static apr_status_t fsp_input_filter(
- ap_filter_t* f, apr_bucket_brigade* bb,
- ap_input_mode_t mode, apr_read_type_e block, apr_off_t nbytes);
-static int fsp_output_filter(ap_filter_t* f, apr_bucket_brigade* bb);
-
-/**
- * Registers the hooks for this module.
- *
- * @param p the pool to allocate from, if necessary.
- */
-static void fsp_register_hooks(apr_pool_t* p)
-{
- // registers the pre-connection hook to handle adding filters
- ap_hook_pre_connection(
- fsp_pre_connection, NULL, NULL, APR_HOOK_MIDDLE);
-
- // will parse a policy file request, to be added in pre_connection
- ap_register_input_filter(
- "fsp_request", fsp_input_filter,
- NULL, AP_FTYPE_CONNECTION);
-
- // will emit a cross-domain policy response to be added in pre_connection
- ap_register_output_filter(
- "fsp_response", fsp_output_filter,
- NULL, AP_FTYPE_CONNECTION);
-}
-
-/**
- * A hook that is called before a connection is handled. This function will
- * get the module configuration and add the flash socket policy filters if
- * a cross-domain policy has been specified in the configuration.
- *
- * @param c the connection.
- * @param csd the connection socket descriptor.
- *
- * @return OK on success.
- */
-static int fsp_pre_connection(conn_rec* c, void* csd)
-{
- // only install filters if a policy was specified in the module config
- fsp_config* cfg = ap_get_module_config(
- c->base_server->module_config, &fsp_module);
- if(cfg->policy != NULL)
- {
- // allocate filter state
- filter_state* state = apr_palloc(c->pool, sizeof(filter_state));
- if(state != NULL)
- {
- // initialize state
- state->cfg = cfg;
- state->checked = state->found = 0;
-
- // add filters
- ap_add_input_filter("fsp_request", state, NULL, c);
- ap_add_output_filter("fsp_response", state, NULL, c);
- }
- }
-
- return OK;
-}
-
-/**
- * Searches the input request for a flash socket policy request. This request,
- * unfortunately, does not follow the HTTP protocol and cannot be handled
- * via a special HTTP handler. Instead, it is a short xml string followed by
- * a null character:
- *
- * '<policy-file-request/>\0'
- *
- * A peek into the incoming data checks the first character of the stream to
- * see if it is '<' (as opposed to typically something else for HTTP). If it
- * is not, then this function returns and HTTP input is read normally. If it
- * is, then the remaining bytes in the policy-file-request are read and
- * checked. If a match is found, then the filter state will be updated to
- * inform the output filter to send a cross-domain policy as a response. If
- * no match is found, HTTP traffic will proceed as usual.
- *
- * @param f the input filter.
- * @param state the filter state.
- *
- * @return APR_SUCCESS on success, some other status on failure.
- */
-static apr_status_t find_policy_file_request(
- ap_filter_t* f, filter_state* state)
-{
- apr_status_t rval = APR_SUCCESS;
-
- // create a temp buffer for speculative reads
- apr_bucket_brigade* tmp = apr_brigade_create(f->c->pool, f->c->bucket_alloc);
-
- // FIXME: not sure how blocking mode works ... can it return fewer than
- // the number of specified bytes?
-
- // peek at the first PFR_LENGTH bytes
- rval = ap_get_brigade(
- f->next, tmp, AP_MODE_SPECULATIVE, APR_BLOCK_READ, PFR_LENGTH);
- if(rval == APR_SUCCESS)
- {
- // quickly check the first bucket for the beginning of a pfr
- const char* data;
- apr_size_t length;
- apr_bucket* b = APR_BRIGADE_FIRST(tmp);
- rval = apr_bucket_read(b, &data, &length, APR_BLOCK_READ);
- if(rval == APR_SUCCESS && length > 0 && data[0] == '<')
- {
- // possible policy file request, fill local buffer
- char pfr[PFR_LENGTH];
- char* ptr = pfr;
- memcpy(ptr, data, length);
- ptr += length;
- memset(ptr, '\0', PFR_LENGTH - length);
- b = APR_BUCKET_NEXT(b);
- while(rval == APR_SUCCESS && b != APR_BRIGADE_SENTINEL(tmp))
- {
- rval = apr_bucket_read(b, &data, &length, APR_BLOCK_READ);
- if(rval == APR_SUCCESS)
- {
- memcpy(ptr, data, length);
- ptr += length;
- b = APR_BUCKET_NEXT(b);
- }
- }
-
- if(rval == APR_SUCCESS)
- {
- // see if pfr is a policy file request: '<policy-file-request/>\0'
- if((ptr - pfr == PFR_LENGTH) && (pfr[PFR_LENGTH - 1] == '\0') &&
- (strncmp(pfr, "<policy-file-request/>", PFR_LENGTH -1) == 0))
- {
- // pfr found
- state->found = 1;
- }
- }
- }
- }
-
- return rval;
-}
-
-/**
- * Handles incoming data. If an attempt has not yet been made to look for
- * a policy request (it is the beginning of the connection), then one is
- * made. Otherwise this filter does nothing.
- *
- * If an attempt is made to find a policy request and one is not found, then
- * reads proceed as normal. If one is found, then the filter state is modified
- * to inform the output filter to send a policy request and the return value
- * of this filter is EOF indicating that the connection should close after
- * sending the cross-domain policy.
- *
- * @param f the input filter.
- * @param bb the brigate to fill with input from the next filters in the chain
- * and then process (look for a policy file request).
- * @param mode the type of read requested (ie: AP_MODE_GETLINE means read until
- * a CRLF is found, AP_MODE_GETBYTES means 'nbytes' of data, etc).
- * @param block APR_BLOCK_READ or APR_NONBLOCK_READ, indicates the type of
- * blocking to do when trying to read.
- * @param nbytes used if the read mode is appropriate to specify the number of
- * bytes to read (set to 0 for AP_MODE_GETLINE).
- *
- * @return the status of the input (ie: APR_SUCCESS for read success, APR_EOF
- * for end of stream, APR_EAGAIN to read again when non-blocking).
- */
-static apr_status_t fsp_input_filter(
- ap_filter_t* f, apr_bucket_brigade* bb,
- ap_input_mode_t mode, apr_read_type_e block, apr_off_t nbytes)
-{
- apr_status_t rval = APR_SUCCESS;
-
- filter_state* state = f->ctx;
- if(state->checked == 1)
- {
- // already checked for policy file request, just read from other filters
- rval = ap_get_brigade(f->next, bb, mode, block, nbytes);
- }
- else
- {
- // try to find a policy file request
- rval = find_policy_file_request(f, state);
- state->checked = 1;
-
- if(rval == APR_SUCCESS)
- {
- if(state->found)
- {
- // do read of PFR_LENGTH bytes, consider end of stream
- rval = ap_get_brigade(
- f->next, bb, AP_MODE_READBYTES, APR_BLOCK_READ, PFR_LENGTH);
- rval = APR_EOF;
- }
- else
- {
- // do normal read
- rval = ap_get_brigade(f->next, bb, mode, block, nbytes);
- }
- }
- }
-
- return rval;
-}
-
-/**
- * Handles outgoing data. If the filter state indicates that a cross-domain
- * policy should be sent then it is added to the outgoing brigade of data. If
- * a policy request was not detected, then this filter makes no changes to
- * the outgoing data.
- *
- * @param f the output filter.
- * @param bb the outgoing brigade of data.
- *
- * @return APR_SUCCESS on success, some other status on error.
- */
-static int fsp_output_filter(ap_filter_t* f, apr_bucket_brigade* bb)
-{
- apr_status_t rval = APR_SUCCESS;
-
- filter_state* state = f->ctx;
- if(state->found)
- {
- // found policy-file-request, add response bucket
- // bucket is immortal because the data is stored in the configuration
- // and doesn't need to be copied
- apr_bucket* head = apr_bucket_immortal_create(
- state->cfg->policy, state->cfg->policy_length, bb->bucket_alloc);
- APR_BRIGADE_INSERT_HEAD(bb, head);
- }
-
- if(rval == APR_SUCCESS)
- {
- // pass brigade to next filter
- rval = ap_pass_brigade(f->next, bb);
- }
-
- return rval;
-}
-
-/**
- * Creates the configuration for this module.
- *
- * @param p the pool to allocate from.
- * @param s the server the configuration is for.
- *
- * @return the configuration data.
- */
-static void* fsp_create_config(apr_pool_t* p, server_rec* s)
-{
- // allocate config
- fsp_config* cfg = apr_palloc(p, sizeof(fsp_config));
-
- // no default policy
- cfg->policy = NULL;
- cfg->policy_length = 0;
- return cfg;
-}
-
-/**
- * Sets the policy file to use from the configuration.
- *
- * @param parms the command directive parameters.
- * @param userdata NULL, not used.
- * @param arg the string argument to the command directive (the file with
- * the cross-domain policy to serve as content).
- *
- * @return NULL on success, otherwise an error string to display.
- */
-static const char* fsp_set_policy_file(
- cmd_parms* parms, void* userdata, const char* arg)
-{
- const char* rval = NULL;
-
- apr_pool_t* pool = (apr_pool_t*)parms->pool;
- fsp_config* cfg = ap_get_module_config(
- parms->server->module_config, &fsp_module);
-
- // ensure command is in the correct context
- rval = ap_check_cmd_context(parms, NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT);
- if(rval == NULL)
- {
- // get canonical file name
- char* fname = ap_server_root_relative(pool, arg);
- if(fname == NULL)
- {
- rval = (const char*)apr_psprintf(
- pool, "%s: Invalid policy file '%s'",
- parms->cmd->name, arg);
- }
- else
- {
- // try to open the file
- apr_status_t rv;
- apr_file_t* fd;
- apr_finfo_t finfo;
- rv = apr_file_open(&fd, fname, APR_READ, APR_OS_DEFAULT, pool);
- if(rv == APR_SUCCESS)
- {
- // stat file
- rv = apr_file_info_get(&finfo, APR_FINFO_NORM, fd);
- if(rv == APR_SUCCESS)
- {
- // ensure file is not empty
- apr_size_t length = (apr_size_t)finfo.size;
- if(length <= 0)
- {
- rval = (const char*)apr_psprintf(
- pool, "%s: policy file '%s' is empty",
- parms->cmd->name, fname);
- }
- // read file
- else
- {
- char* buf = (char*)apr_palloc(pool, length + 1);
- buf[length] = '\0';
- rv = apr_file_read_full(fd, buf, length, NULL);
- if(rv == APR_SUCCESS)
- {
- // TODO: validate file
- // save policy string
- cfg->policy = buf;
- cfg->policy_length = length + 1;
- }
- }
-
- // close the file
- apr_file_close(fd);
- }
- }
-
- // handle error case
- if(rv != APR_SUCCESS)
- {
- char errmsg[120];
- rval = (const char*)apr_psprintf(
- pool, "%s: Invalid policy file '%s' (%s)",
- parms->cmd->name, fname,
- apr_strerror(rv, errmsg, sizeof(errmsg)));
- }
- }
- }
-
- return rval;
-}
-
-// table of configuration directives
-static const command_rec fsp_cmds[] =
-{
- AP_INIT_TAKE1(
- "FSPPolicyFile", /* the directive */
- fsp_set_policy_file, /* function to call when directive is found */
- NULL, /* user data to pass to function, not used */
- RSRC_CONF, /* indicates the directive appears outside of <Location> */
- "FSPPolicyFile (string) The cross-domain policy file to use"), /* docs */
- {NULL}
-};
-
-// module setup
-module AP_MODULE_DECLARE_DATA fsp_module =
-{
- STANDARD20_MODULE_STUFF, /* stuff declared in every 2.0 mod */
- NULL, /* create per-directory config structure */
- NULL, /* merge per-directory config structures */
- fsp_create_config, /* create per-server config structure */
- NULL, /* merge per-server config structures */
- fsp_cmds, /* command apr_table_t */
- fsp_register_hooks /* register hooks */
-};