Exemplo n.º 1
0
/*
 * resolve and validate an access_token against the configured Authorization Server
 */
static apr_byte_t oidc_oauth_resolve_access_token(request_rec *r, oidc_cfg *c,
		const char *access_token, json_t **token, char **response) {

	json_t *result = NULL;
	const char *json = NULL;

	/* see if we've got the claims for this access_token cached already */
	c->cache->get(r, OIDC_CACHE_SECTION_ACCESS_TOKEN, access_token, &json);

	if (json == NULL) {

		/* not cached, go out and validate the access_token against the Authorization server and get the JSON claims back */
		if (oidc_oauth_validate_access_token(r, c, access_token, &json) == FALSE) {
			oidc_error(r,
					"could not get a validation response from the Authorization server");
			return FALSE;
		}

		/* decode and see if it is not an error response somehow */
		if (oidc_util_decode_json_and_check_error(r, json, &result) == FALSE)
			return FALSE;

		json_t *active = json_object_get(result, "active");
		if (active != NULL) {

			if ((!json_is_boolean(active)) || (!json_is_true(active))) {
				oidc_debug(r,
						"no \"active\" boolean object with value \"true\" found in response JSON object");
				json_decref(result);
				return FALSE;
			}

			json_t *exp = json_object_get(result, "exp");
			if ((exp != NULL) && (json_is_number(exp))) {
				/* set it in the cache so subsequent request don't need to validate the access_token and get the claims anymore */
				c->cache->set(r, OIDC_CACHE_SECTION_ACCESS_TOKEN, access_token, json,
						apr_time_from_sec(json_integer_value(exp)));
			} else if (json_integer_value(exp) <= 0) {
				oidc_debug(r,
						"response JSON object did not contain an \"exp\" integer number; introspection result will not be cached");
			}

		} else {

			/* assume PingFederate validation: get and check the expiry timestamp */
			json_t *expires_in = json_object_get(result, "expires_in");
			if ((expires_in == NULL) || (!json_is_number(expires_in))) {
				oidc_error(r,
						"response JSON object did not contain an \"expires_in\" number");
				json_decref(result);
				return FALSE;
			}
			if (json_integer_value(expires_in) <= 0) {
				oidc_warn(r,
						"\"expires_in\" number <= 0 (%" JSON_INTEGER_FORMAT "); token already expired...",
						json_integer_value(expires_in));
				json_decref(result);
				return FALSE;
			}

			/* set it in the cache so subsequent request don't need to validate the access_token and get the claims anymore */
			c->cache->set(r, OIDC_CACHE_SECTION_ACCESS_TOKEN, access_token, json,
					apr_time_now() + apr_time_from_sec(json_integer_value(expires_in)));
		}


	} else {

		/* we got the claims for this access_token in our cache, decode it in to a JSON structure */
		json_error_t json_error;
		result = json_loads(json, 0, &json_error);
		if (result == NULL) {
			oidc_error(r, "cached JSON was corrupted: %s", json_error.text);
			return FALSE;
		}
	}

	/* return the access_token JSON object */
	json_t *tkn = json_object_get(result, "access_token");
	if ((tkn != NULL) && (json_is_object(tkn))) {

		/*
		 * assume PingFederate validation: copy over those claims from the access_token
		 * that are relevant for authorization purposes
		 */
		json_object_set(tkn, "client_id", json_object_get(result, "client_id"));
		json_object_set(tkn, "scope", json_object_get(result, "scope"));

		//oidc_oauth_spaced_string_to_array(r, result, "scope", tkn, "scopes");

		/* return only the pimped access_token results */
		*token = json_deep_copy(tkn);
		char *s_token = json_dumps(*token, 0);
		*response = apr_pstrdup(r->pool, s_token);
		free(s_token);

		json_decref(result);

	} else  {

		//oidc_oauth_spaced_string_to_array(r, result, "scope", result, "scopes");

		/* assume spec compliant introspection */
		*token = result;
		*response = apr_pstrdup(r->pool, json);

	}

	return TRUE;
}
Exemplo n.º 2
0
/* return 0 means OK, return -1 means ERROR */
static int update_expired_data_from_local_file_info (request_rec *r,
                                                     LOCAL_FILE_INFO *p_local_file_info)
{
    apr_size_t len;
    char errmsg_buf[120];
    apr_pool_t *rp = r->pool;
    apr_status_t rv;
    apr_file_t *fp;
    apr_finfo_t finfo;
    char *file_content;
    apr_size_t flen;
    apr_time_t cur_time = apr_time_now ();

        /* open file */
    rv = apr_file_open (&fp, p_local_file_info->local_file,
                        APR_READ, APR_OS_DEFAULT, rp);
    if (rv != APR_SUCCESS) {
        apr_strerror (rv, errmsg_buf, sizeof (errmsg_buf));
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                      "fail to open file: %s", errmsg_buf);
        return -1;
    }

        /* get file info */
    rv = apr_file_info_get(&finfo, APR_FINFO_NORM, fp);
    if (rv != APR_SUCCESS) {
        apr_strerror (rv, errmsg_buf, sizeof (errmsg_buf));
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                      "fail to get file info: %s", errmsg_buf);
        return -1;
    }

    if (finfo.filetype != APR_REG) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                      "the type of local file is not valid");
        return -1;
    }
    
        /* get the file_content*/
    if (!(p_local_file_info->last_update_file)
        || strcmp (finfo.fname, p_local_file_info->last_update_file) != 0
        || p_local_file_info->last_update_time < finfo.mtime) {
        file_content = apr_palloc (rp, finfo.size + 2);
        if (get_content_from_file (r, fp, finfo, file_content, &flen) == -1)
            return -1;

#ifdef DEBUG
        file_content[flen] = '\0';
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
                      "file_content: %s", file_content);
#endif

            /* clear the pool, preventing leakage */
        apr_pool_clear (p_local_file_info->subpool);
            /* update last_update_file */
        p_local_file_info->last_update_file =
            apr_pstrdup (p_local_file_info->subpool, finfo.fname);
            /* update last_update_time */
        p_local_file_info->last_update_time = finfo.mtime;
            /* get the ipsubnet_list from file_content*/
        file_content[flen] = '\n';
        get_ipsubnet_list_from_file_content(r,
                                            p_local_file_info->subpool,
                                            file_content,
                                            flen,
                                            &(p_local_file_info->p_ipsubnet_list));
    }
    
    return 0;
}
Exemplo n.º 3
0
static void justsleep(abts_case *tc, void *data)
{
    apr_int32_t nsds;
    const apr_pollfd_t *hot_files;
    apr_pollset_t *pollset;
    apr_status_t rv;
    apr_time_t t1, t2;
    int i;
    apr_pollset_method_e methods[] = {
        APR_POLLSET_DEFAULT,
        APR_POLLSET_SELECT,
        APR_POLLSET_KQUEUE,
        APR_POLLSET_PORT,
        APR_POLLSET_EPOLL,
        APR_POLLSET_POLL};

    nsds = 1;
    t1 = apr_time_now();
    rv = apr_poll(NULL, 0, &nsds, apr_time_from_msec(200));
    t2 = apr_time_now();
    ABTS_INT_EQUAL(tc, 1, APR_STATUS_IS_TIMEUP(rv));
    ABTS_INT_EQUAL(tc, 0, nsds);
    ABTS_ASSERT(tc,
                "apr_poll() didn't sleep",
                (t2 - t1) > apr_time_from_msec(100));

    for (i = 0; i < sizeof methods / sizeof methods[0]; i++) {
        rv = apr_pollset_create_ex(&pollset, 5, p, 0, methods[i]);
        if (rv != APR_ENOTIMPL) {
            ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);

            nsds = 1;
            t1 = apr_time_now();
            rv = apr_pollset_poll(pollset, apr_time_from_msec(200), &nsds,
                                  &hot_files);
            t2 = apr_time_now();
            ABTS_INT_EQUAL(tc, 1, APR_STATUS_IS_TIMEUP(rv));
            ABTS_INT_EQUAL(tc, 0, nsds);
            ABTS_ASSERT(tc,
                        "apr_pollset_poll() didn't sleep",
                        (t2 - t1) > apr_time_from_msec(100));

            rv = apr_pollset_destroy(pollset);
            ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
        }

        rv = apr_pollcb_create_ex(&pollcb, 5, p, 0, methods[0]);
        if (rv != APR_ENOTIMPL) {
            ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);

            t1 = apr_time_now();
            rv = apr_pollcb_poll(pollcb, apr_time_from_msec(200), NULL, NULL);
            t2 = apr_time_now();
            ABTS_INT_EQUAL(tc, 1, APR_STATUS_IS_TIMEUP(rv));
            ABTS_ASSERT(tc,
                        "apr_pollcb_poll() didn't sleep",
                        (t2 - t1) > apr_time_from_msec(100));

            /* no apr_pollcb_destroy() */
        }
    }
}
Exemplo n.º 4
0
JIT_Result compile_do_compilation_jit(Method* method, JIT* jit)
{
    // Time stamp for counting the total compilation time
    apr_time_t start;

    Global_Env * vm_env = VM_Global_State::loader_env;

    assert(method);
    assert(jit);

    if (!parallel_jit) {
        vm_env->p_jit_a_method_lock->_lock();
        // MikhailF reports that each JIT in recompilation chain has its own
        // JIT* pointer.
        // If in addition to recompilation chains one adds recompilation loops,
        // this check can be skipped, or main_code_chunk_id should be
        // modified.

        if (NULL != method->get_chunk_info_no_create_mt(jit, CodeChunkInfo::main_code_chunk_id)) {
            vm_env->p_jit_a_method_lock->_unlock();
            return JIT_SUCCESS;
        }
    }

    OpenMethodExecutionParams flags = {0}; 
    jvmti_get_compilation_flags(&flags);
    flags.exe_insert_write_barriers = gc_requires_barriers();

    Compilation_Handle ch;
    ch.env = VM_Global_State::loader_env;
    ch.jit = jit;

    start = apr_time_now();

    TRACE("compile_do_compilation_jit(): calling jit->compile_method_with_params() for method " << method );

    JIT_Result res = jit->compile_method_with_params(&ch, method, flags);

    TRACE("compile_do_compilation_jit(): returned from jit->compile_method_with_params() for method " << method );

    UNSAFE_REGION_START
    // Non-atomic increment of statistic counter
    // Conversion from microseconds to milliseconds
    vm_env->total_compilation_time += ((apr_time_now() - start)/1000);
    UNSAFE_REGION_END

    if (JIT_SUCCESS != res) {
        if (!parallel_jit) {
            vm_env->p_jit_a_method_lock->_unlock();
        }
        return res;
    }

    method->lock();
    for (CodeChunkInfo* cci = method->get_first_JIT_specific_info();  cci;  cci = cci->_next) {
        if (cci->get_jit() == jit) {
            compile_flush_generated_code_block((U_8*)cci->get_code_block_addr(), cci->get_code_block_size());
            // We assume the main chunk starts from entry point
            if (cci->get_id() == CodeChunkInfo::main_code_chunk_id) {
                method->set_code_addr(cci->get_code_block_addr());
            }
        }
    }

    // Commit the compilation by setting the method's code address
    method->set_state(Method::ST_Compiled);
    method->do_jit_recompiled_method_callbacks();
    method->apply_vtable_patches();
    method->unlock();
    if (!parallel_jit) {
        vm_env->p_jit_a_method_lock->_unlock();
    }

    // Find TI environment
    DebugUtilsTI *ti = vm_env->TI;

    // Call TI callbacks
    if (jvmti_should_report_event(JVMTI_EVENT_COMPILED_METHOD_LOAD)
        && ti->getPhase() == JVMTI_PHASE_LIVE)
    {
        jvmti_send_chunks_compiled_method_load_event(method);
    }
    return JIT_SUCCESS;
}
Exemplo n.º 5
0
APREQ_DECLARE(int) apreq_cookie_serialize(const apreq_cookie_t *c,
                                          char *buf, apr_size_t len)
{
    /*  The format string must be large enough to accomodate all
     *  of the cookie attributes.  The current attributes sum to
     *  ~90 characters (w/ 6-8 padding chars per attr), so anything
     *  over 100 should be fine.
     */

    unsigned version = apreq_cookie_version(c);
    char format[128] = "%s=%s";
    char *f = format + strlen(format);

    /* XXX protocol enforcement (for debugging, anyway) ??? */

    if (c->v.name == NULL)
        return -1;

#define NULL2EMPTY(attr) (attr ? attr : "")


    if (version == NETSCAPE) {
        char expires[APR_RFC822_DATE_LEN] = {0};

#define ADD_NS_ATTR(name) do {                  \
    if (c->name != NULL)                        \
        strcpy(f, "; " #name "=%s");            \
    else                                        \
        strcpy(f, "%0.s");                      \
    f += strlen(f);                             \
} while (0)

        ADD_NS_ATTR(path);
        ADD_NS_ATTR(domain);

        if (c->max_age != -1) {
            strcpy(f, "; expires=%s");
            apr_rfc822_date(expires, c->max_age + apr_time_now());
            expires[7] = '-';
            expires[11] = '-';
        }
        else
            strcpy(f, "");

        f += strlen(f);

        if (apreq_cookie_is_secure(c))
            strcpy(f, "; secure");

        f += strlen(f);

        if (apreq_cookie_is_httponly(c))
            strcpy(f, "; HttpOnly");

        return apr_snprintf(buf, len, format, c->v.name, c->v.data,
           NULL2EMPTY(c->path), NULL2EMPTY(c->domain), expires);
    }

    /* c->version == RFC */

    strcpy(f,"; Version=%u");
    f += strlen(f);

/* ensure RFC attributes are always quoted */
#define ADD_RFC_ATTR(name) do {                 \
    if (c->name != NULL)                        \
        if (*c->name == '"')                    \
            strcpy(f, "; " #name "=%s");        \
        else                                    \
            strcpy(f, "; " #name "=\"%s\"");    \
    else                                        \
        strcpy(f, "%0.s");                      \
    f += strlen (f);                            \
} while (0)

    ADD_RFC_ATTR(path);
    ADD_RFC_ATTR(domain);
    ADD_RFC_ATTR(port);
    ADD_RFC_ATTR(comment);
    ADD_RFC_ATTR(commentURL);

    strcpy(f, c->max_age != -1 ? "; max-age=%" APR_TIME_T_FMT : "");

    f += strlen(f);

    if (apreq_cookie_is_secure(c))
        strcpy(f, "; secure");

    f += strlen(f);

    if (apreq_cookie_is_httponly(c))
        strcpy(f, "; HttpOnly");

    return apr_snprintf(buf, len, format, c->v.name, c->v.data, version,
                        NULL2EMPTY(c->path), NULL2EMPTY(c->domain),
                        NULL2EMPTY(c->port), NULL2EMPTY(c->comment),
                        NULL2EMPTY(c->commentURL), apr_time_sec(c->max_age));
}
Exemplo n.º 6
0
apr_status_t h2_filter_core_input(ap_filter_t* f,
                                  apr_bucket_brigade* brigade,
                                  ap_input_mode_t mode,
                                  apr_read_type_e block,
                                  apr_off_t readbytes) 
{
    h2_filter_cin *cin = f->ctx;
    apr_status_t status = APR_SUCCESS;
    apr_interval_time_t saved_timeout = UNSET;
    
    ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, f->c,
                  "core_input(%ld): read, %s, mode=%d, readbytes=%ld", 
                  (long)f->c->id, (block == APR_BLOCK_READ)? "BLOCK_READ" : "NONBLOCK_READ", 
                  mode, (long)readbytes);
    
    if (mode == AP_MODE_INIT || mode == AP_MODE_SPECULATIVE) {
        return ap_get_brigade(f->next, brigade, mode, block, readbytes);
    }
    
    if (mode != AP_MODE_READBYTES) {
        return (block == APR_BLOCK_READ)? APR_SUCCESS : APR_EAGAIN;
    }
    
    if (!cin->bb) {
        cin->bb = apr_brigade_create(cin->pool, f->c->bucket_alloc);
    }

    if (!cin->socket) {
        cin->socket = ap_get_conn_socket(f->c);
    }
    
    cin->start_read = apr_time_now();
    if (APR_BRIGADE_EMPTY(cin->bb)) {
        /* We only do a blocking read when we have no streams to process. So,
         * in httpd scoreboard lingo, we are in a KEEPALIVE connection state.
         * When reading non-blocking, we do have streams to process and update
         * child with NULL request. That way, any current request information
         * in the scoreboard is preserved.
         */
        if (block == APR_BLOCK_READ) {
            if (cin->timeout > 0) {
                apr_socket_timeout_get(cin->socket, &saved_timeout);
                apr_socket_timeout_set(cin->socket, cin->timeout);
            }
        }
        status = ap_get_brigade(f->next, cin->bb, AP_MODE_READBYTES,
                                block, readbytes);
        if (saved_timeout != UNSET) {
            apr_socket_timeout_set(cin->socket, saved_timeout);
        }
    }
    
    switch (status) {
        case APR_SUCCESS:
            status = consume_brigade(cin, cin->bb, block);
            break;
        case APR_EOF:
        case APR_EAGAIN:
        case APR_TIMEUP:
            ap_log_cerror(APLOG_MARK, APLOG_TRACE1, status, f->c,
                          "core_input(%ld): read", (long)f->c->id);
            break;
        default:
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, f->c, APLOGNO(03046)
                          "h2_conn_io: error reading");
            break;
    }
    return status;
}
Exemplo n.º 7
0
int
main ( int argc, char *argv[] )
{
   int rc;
   struct stat struct_stat;
   pthread_t pid;
   pthread_attr_t attr;
   int i, num_sources;
   uid_t gmetad_uid;
   mode_t rrd_umask;
   char * gmetad_username;
   struct passwd *pw;
   gmetad_config_t *c = &gmetad_config;
   apr_interval_time_t sleep_time;
   apr_time_t summary_started, now;
   double random_sleep_factor;
   unsigned int rand_seed;

   rc = apr_initialize();
   if (rc != APR_SUCCESS) {
      return -1;
   }

   /* create a memory pool. */
   apr_pool_create(&global_context, NULL);

   /* Ignore SIGPIPE */
   signal( SIGPIPE, SIG_IGN );

   initialize_scoreboard();

   /* Mark the time this gmetad started */
   started = apr_time_now();

   if (cmdline_parser(argc, argv, &args_info) != 0)
      err_quit("command-line parser error");

   num_sources = number_of_datasources( args_info.conf_arg );
   if(!num_sources)
      {
         err_quit("%s doesn't have any data sources specified", args_info.conf_arg);
      }

   memset(&root, 0, sizeof(root));
   root.id = ROOT_NODE;

   /* Get the real number of data sources later */
   sources = hash_create( num_sources + 10 );
   if (! sources )
      {
         err_quit("Unable to create sources hash\n");
      }

   root.authority = hash_create( num_sources + 10 );
   if (!root.authority)
      {
         err_quit("Unable to create root authority (our grids and clusters) hash\n");
      }

   root.metric_summary = hash_create (DEFAULT_METRICSIZE);
   if (!root.metric_summary)
      {
         err_quit("Unable to create root summary hash");
      }

   parse_config_file ( args_info.conf_arg );
    /* If given, use command line directives over config file ones. */
   if (args_info.debug_given)
      {
         c->debug_level = args_info.debug_arg;
      }
   debug_level = c->debug_level;
   set_debug_msg_level(debug_level);

   /* Setup our default authority pointer if the conf file hasnt yet.
    * Done in the style of hash node strings. */
   if (!root.stringslen)
      {
         gethostname(hostname, HOSTNAMESZ);
         root.authority_ptr = 0;
         sprintf(root.strings, "http://%s/ganglia/", hostname);
         root.stringslen += strlen(root.strings) + 1;
      }

   rand_seed = apr_time_now() * (int)pthread_self();
   for(i = 0; i < root.stringslen; rand_seed = rand_seed * root.strings[i++]);

   /* Debug level 1 is error output only, and no daemonizing. */
   if (!debug_level)
      {
         rrd_umask = c->umask;
         daemon_init (argv[0], 0, rrd_umask);
      }

   if (args_info.pid_file_given)
     {
       update_pidfile (args_info.pid_file_arg);
     }

   /* The rrd_rootdir must be writable by the gmetad process */
   if( c->should_setuid )
      {
         if(! (pw = getpwnam(c->setuid_username)))
            {
               err_sys("Getpwnam error");
            }
         gmetad_uid = pw->pw_uid;
         gmetad_username = c->setuid_username;
      }
   else
      {
         gmetad_uid = getuid();
         if(! (pw = getpwuid(gmetad_uid)))
            {
               err_sys("Getpwnam error");
            } 
         gmetad_username = strdup(pw->pw_name);
      }

   debug_msg("Going to run as user %s", gmetad_username);
   if( c->should_setuid )
      {
         become_a_nobody(c->setuid_username);
      }

   if( c->write_rrds )
      {
         if( stat( c->rrd_rootdir, &struct_stat ) )
            {
                err_sys("Please make sure that %s exists", c->rrd_rootdir);
            }
         if ( struct_stat.st_uid != gmetad_uid )
            {
                err_quit("Please make sure that %s is owned by %s", c->rrd_rootdir, gmetad_username);
            }
         if (! (struct_stat.st_mode & S_IWUSR) )
            {
                err_quit("Please make sure %s has WRITE permission for %s", gmetad_username, c->rrd_rootdir);
            }
      }

   if(debug_level)
      {
         fprintf(stderr,"Sources are ...\n");
         hash_foreach( sources, print_sources, NULL);
      }

#ifdef WITH_MEMCACHED
   if (c->memcached_parameters != NULL)
      {
         memcached_connection_pool = memcached_pool(c->memcached_parameters, strlen(c->memcached_parameters));
      }
#endif /* WITH_MEMCACHED */

   server_socket = g_tcp_socket_server_new( c->xml_port );
   if (server_socket == NULL)
      {
         err_quit("tcp_listen() on xml_port failed");
      }
   debug_msg("xml listening on port %d", c->xml_port);
   
   interactive_socket = g_tcp_socket_server_new( c->interactive_port );
   if (interactive_socket == NULL)
      {
         err_quit("tcp_listen() on interactive_port failed");
      }
   debug_msg("interactive xml listening on port %d", c->interactive_port);

    /* Forward metrics to Graphite using carbon protocol */
    if (c->carbon_server != NULL)
      {
         if (!strcmp(c->carbon_protocol, "udp"))
            {
               carbon_udp_socket = init_carbon_udp_socket (c->carbon_server, c->carbon_port);

               if (carbon_udp_socket == NULL)
                  err_quit("carbon %s socket failed for %s:%d", c->carbon_protocol, c->carbon_server, c->carbon_port);
            }
         debug_msg("carbon forwarding ready to send via %s to %s:%d", c->carbon_protocol, c->carbon_server, c->carbon_port);
      }

#ifdef WITH_RIEMANN
    if (c->riemann_server !=NULL)
      {
         if (!strcmp(c->riemann_protocol, "udp"))
            {
               riemann_udp_socket = init_riemann_udp_socket (c->riemann_server, c->riemann_port);

               if (riemann_udp_socket == NULL)
                  err_quit("[riemann] %s socket failed for %s:%d", c->riemann_protocol, c->riemann_server, c->riemann_port);
            } else if (!strcmp(c->riemann_protocol, "tcp")) {
                riemann_tcp_socket = init_riemann_tcp_socket (c->riemann_server, c->riemann_port);
                if (riemann_tcp_socket == NULL) {
                   riemann_circuit_breaker = RIEMANN_CB_OPEN;
                   riemann_reset_timeout = apr_time_now () + RIEMANN_RETRY_TIMEOUT * APR_USEC_PER_SEC;
                } else {
                   riemann_circuit_breaker = RIEMANN_CB_CLOSED;
                   riemann_failures = 0;
                }
            } else {
                err_quit("ERROR: Riemann protocol must be 'udp' or 'tcp'");
            }
         debug_msg("[riemann] Ganglia configured to forward metrics via %s to %s:%d", c->riemann_protocol, c->riemann_server, c->riemann_port);
      }
#endif /* WITH_RIEMANN */

   /* initialize summary mutex */
   root.sum_finished = (pthread_mutex_t *) 
                          malloc(sizeof(pthread_mutex_t));
   pthread_mutex_init(root.sum_finished, NULL);

   pthread_attr_init( &attr );
   pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_DETACHED );

   /* Spin off the non-interactive server threads. (Half as many as interactive). */
   for (i=0; i < c->server_threads/2; i++)
      pthread_create(&pid, &attr, server_thread, (void*) 0);

   /* Spin off the interactive server threads. */
   for (i=0; i < c->server_threads; i++)
      pthread_create(&pid, &attr, server_thread, (void*) 1);

   hash_foreach( sources, spin_off_the_data_threads, NULL );

   /* A thread to cleanup old metrics and hosts */
   pthread_create(&pid, &attr, cleanup_thread, (void *) NULL);
   debug_msg("cleanup thread has been started");

#ifdef WITH_RIEMANN
   if (!strcmp(c->riemann_protocol, "tcp")) {
      /* A thread to re-poll riemann TCP port if circuit breaker tripped */
      pthread_create(&pid, &attr, circuit_breaker_thread, (void *) NULL);
      debug_msg ("[riemann] circuit breaker thread has been started");
   }
#endif /* WITH_RIEMANN */

    /* Meta data */
   last_metadata = apr_time_now();  //Updating global variable
   for(;;)
      {
         /* Do at a random interval, between 
                 (shortest_step/2) +/- METADATA_SLEEP_RANDOMIZE percent */
         random_sleep_factor = (1 + (METADATA_SLEEP_RANDOMIZE / 50.0) * ((rand_r(&rand_seed) - RAND_MAX/2)/(float)RAND_MAX));
         sleep_time = random_sleep_factor * apr_time_from_sec(c->shortest_step) / 2;
         /* Make sure the sleep time is at least 1 second */
         if(apr_time_sec(apr_time_now() + sleep_time) < (METADATA_MINIMUM_SLEEP + apr_time_sec(apr_time_now())))
            sleep_time += apr_time_from_sec(METADATA_MINIMUM_SLEEP);
         apr_sleep(sleep_time);

         /* Need to be sure root is locked while doing summary */
         pthread_mutex_lock(root.sum_finished);

         summary_started = apr_time_now();
         /* Flush the old values */
         hash_foreach(root.metric_summary, zero_out_summary, NULL);
         root.hosts_up = 0;
         root.hosts_down = 0;

         /* Sum the new values */
         hash_foreach(root.authority, do_root_summary, NULL );

         /* summary completed */
         pthread_mutex_unlock(root.sum_finished);

         /* Save them to RRD */
         hash_foreach(root.metric_summary, write_root_summary, NULL);

         /* Remember our last run */
         now = apr_time_now();
         last_metadata = now;  //Updating global variable
         ganglia_scoreboard_incby(METS_SUMRZ_DURATION, now - summary_started);
      }

   apr_pool_destroy(global_context);

   apr_terminate();
   return 0;
}
Exemplo n.º 8
0
IDATA thread_sleep_impl(I_64 millis, IDATA nanos, IDATA interruptable) {
    IDATA status;
    IDATA result;
    hythread_t self;
    hythread_monitor_t mon;

    if (nanos == 0 && millis == 0) {
        hythread_yield();
        return TM_ERROR_NONE;
    }
    if (!(self = hythread_self())) {
        // Report error in case current thread is not attached
        return TM_ERROR_UNATTACHED_THREAD;
    }

    // Grab thread monitor
    mon = self->monitor;
    status = hythread_monitor_enter(mon);
    assert(status == TM_ERROR_NONE);
    assert(mon->recursion_count == 0);
    mon->owner = NULL;
    mon->wait_count++;

    // Set thread state
    status = port_mutex_lock(&self->mutex);
    assert(status == TM_ERROR_NONE);
    self->waited_monitor = mon;
    self->state |= TM_THREAD_STATE_SLEEPING;
    status = port_mutex_unlock(&self->mutex);
    assert(status == TM_ERROR_NONE);

    do {
        apr_time_t start;
        assert(mon->notify_count >= 0);
        assert(mon->notify_count < mon->wait_count);
        start = apr_time_now();

        result = condvar_wait_impl(&mon->condition, &mon->mutex, millis, nanos, interruptable);
        if (result != TM_ERROR_NONE) {
            break;
        }
        // we should not change millis and nanos if both are 0 (meaning "no timeout")
        if (millis || nanos) {
            apr_interval_time_t elapsed = apr_time_now() - start;
            nanos -= (IDATA)((elapsed % 1000) * 1000);
            if (nanos < 0) {
                millis -= elapsed/1000 + 1;
                nanos += 1000000;
            } else {
                millis -= elapsed/1000;
            }
            if (millis < 0) {
                assert(status == TM_ERROR_NONE);
                status = TM_ERROR_TIMEOUT;
                break;
            }
            assert(0 <= nanos && nanos < 1000000);
        }
    } while(1);

    // Restore thread state
    status = port_mutex_lock(&self->mutex);
    assert(status == TM_ERROR_NONE);
    self->state &= ~TM_THREAD_STATE_SLEEPING;
    self->waited_monitor = NULL;
    status = port_mutex_unlock(&self->mutex);
    assert(status == TM_ERROR_NONE);

    // Release thread monitor
    mon->wait_count--;
    mon->owner = self;
    assert(mon->notify_count <= mon->wait_count);
    status = hythread_monitor_exit(mon);
    assert(status == TM_ERROR_NONE);

    if (self->request) {
        hythread_safe_point();
        hythread_exception_safe_point();
    }

    return (result == TM_ERROR_INTERRUPT && interruptable)
        ? TM_ERROR_INTERRUPT : TM_ERROR_NONE;
}
Exemplo n.º 9
0
AP_DECLARE(void) ap_reclaim_child_processes(int terminate,
                                            ap_reclaim_callback_fn_t *mpm_callback)
{
    apr_time_t waittime = 1024 * 16;
    int i;
    extra_process_t *cur_extra;
    int not_dead_yet;
    int max_daemons;
    apr_time_t starttime = apr_time_now();
    /* this table of actions and elapsed times tells what action is taken
     * at which elapsed time from starting the reclaim
     */
    struct {
        action_t action;
        apr_time_t action_time;
    } action_table[] = {
        {DO_NOTHING, 0}, /* dummy entry for iterations where we reap
                          * children but take no action against
                          * stragglers
                          */
        {SEND_SIGTERM, apr_time_from_sec(3)},
        {SEND_SIGTERM, apr_time_from_sec(5)},
        {SEND_SIGTERM, apr_time_from_sec(7)},
        {SEND_SIGKILL, apr_time_from_sec(9)},
        {GIVEUP,       apr_time_from_sec(10)}
    };
    int cur_action;      /* index of action we decided to take this
                          * iteration
                          */
    int next_action = 1; /* index of first real action */

    ap_mpm_query(AP_MPMQ_MAX_DAEMON_USED, &max_daemons);

    do {
        apr_sleep(waittime);
        /* don't let waittime get longer than 1 second; otherwise, we don't
         * react quickly to the last child exiting, and taking action can
         * be delayed
         */
        waittime = waittime * 4;
        if (waittime > apr_time_from_sec(1)) {
            waittime = apr_time_from_sec(1);
        }

        /* see what action to take, if any */
        if (action_table[next_action].action_time <= apr_time_now() - starttime) {
            cur_action = next_action;
            ++next_action;
        }
        else {
            cur_action = 0; /* nothing to do */
        }

        /* now see who is done */
        not_dead_yet = 0;
        for (i = 0; i < max_daemons; ++i) {
            process_score *ps = ap_get_scoreboard_process(i);
            pid_t pid = ps->pid;

            if (pid == 0) {
                continue; /* not every scoreboard entry is in use */
            }

            if (reclaim_one_pid(pid, action_table[cur_action].action)) {
                mpm_callback(i, 0, 0);
            }
            else {
                ++not_dead_yet;
            }
        }

        cur_extra = extras;
        while (cur_extra) {
            ap_generation_t old_gen;
            extra_process_t *next = cur_extra->next;

            if (reclaim_one_pid(cur_extra->pid, action_table[cur_action].action)) {
                if (ap_unregister_extra_mpm_process(cur_extra->pid, &old_gen) == 1) {
                    mpm_callback(-1, cur_extra->pid, old_gen);
                }
                else {
                    AP_DEBUG_ASSERT(1 == 0);
                }
            }
            else {
                ++not_dead_yet;
            }
            cur_extra = next;
        }
#if APR_HAS_OTHER_CHILD
        apr_proc_other_child_refresh_all(APR_OC_REASON_RESTART);
#endif

    } while (not_dead_yet > 0 &&
             action_table[cur_action].action != GIVEUP);
}
Exemplo n.º 10
0
static request_rec *h2_task_create_request(h2_task_env *env)
{
    conn_rec *conn = env->conn->c;
    request_rec *r;
    apr_pool_t *p;
    int access_status = HTTP_OK;    
    
    apr_pool_create(&p, conn->pool);
    apr_pool_tag(p, "request");
    r = apr_pcalloc(p, sizeof(request_rec));
    AP_READ_REQUEST_ENTRY((intptr_t)r, (uintptr_t)conn);
    r->pool            = p;
    r->connection      = conn;
    r->server          = conn->base_server;
    
    r->user            = NULL;
    r->ap_auth_type    = NULL;
    
    r->allowed_methods = ap_make_method_list(p, 2);
    
    r->headers_in = apr_table_copy(r->pool, env->headers);
    r->trailers_in     = apr_table_make(r->pool, 5);
    r->subprocess_env  = apr_table_make(r->pool, 25);
    r->headers_out     = apr_table_make(r->pool, 12);
    r->err_headers_out = apr_table_make(r->pool, 5);
    r->trailers_out    = apr_table_make(r->pool, 5);
    r->notes           = apr_table_make(r->pool, 5);
    
    r->request_config  = ap_create_request_config(r->pool);
    /* Must be set before we run create request hook */
    
    r->proto_output_filters = conn->output_filters;
    r->output_filters  = r->proto_output_filters;
    r->proto_input_filters = conn->input_filters;
    r->input_filters   = r->proto_input_filters;
    ap_run_create_request(r);
    r->per_dir_config  = r->server->lookup_defaults;
    
    r->sent_bodyct     = 0;                      /* bytect isn't for body */
    
    r->read_length     = 0;
    r->read_body       = REQUEST_NO_BODY;
    
    r->status          = HTTP_OK;  /* Until further notice */
    r->header_only     = 0;
    r->the_request     = NULL;
    
    /* Begin by presuming any module can make its own path_info assumptions,
     * until some module interjects and changes the value.
     */
    r->used_path_info = AP_REQ_DEFAULT_PATH_INFO;
    
    r->useragent_addr = conn->client_addr;
    r->useragent_ip = conn->client_ip;
    
    ap_run_pre_read_request(r, conn);
    
    /* Time to populate r with the data we have. */
    r->request_time = apr_time_now();
    r->the_request = apr_psprintf(r->pool, "%s %s HTTP/1.1", 
                                  env->method, env->path);
    r->method = env->method;
    /* Provide quick information about the request method as soon as known */
    r->method_number = ap_method_number_of(r->method);
    if (r->method_number == M_GET && r->method[0] == 'H') {
        r->header_only = 1;
    }

    ap_parse_uri(r, env->path);
    r->protocol = (char*)"HTTP/1.1";
    r->proto_num = HTTP_VERSION(1, 1);
    
    r->hostname = env->authority;
    
    /* update what we think the virtual host is based on the headers we've
     * now read. may update status.
     */
    ap_update_vhost_from_headers(r);
    
    /* we may have switched to another server */
    r->per_dir_config = r->server->lookup_defaults;
    
    /*
     * Add the HTTP_IN filter here to ensure that ap_discard_request_body
     * called by ap_die and by ap_send_error_response works correctly on
     * status codes that do not cause the connection to be dropped and
     * in situations where the connection should be kept alive.
     */
    ap_add_input_filter_handle(ap_http_input_filter_handle,
                               NULL, r, r->connection);
    
    if (access_status != HTTP_OK
        || (access_status = ap_run_post_read_request(r))) {
        ap_die(access_status, r);
        ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r);
        ap_run_log_transaction(r);
        r = NULL;
        goto traceout;
    }
    
    AP_READ_REQUEST_SUCCESS((uintptr_t)r, (char *)r->method, 
                            (char *)r->uri, (char *)r->server->defn_name, 
                            r->status);
    return r;
traceout:
    AP_READ_REQUEST_FAILURE((uintptr_t)r);
    return r;
}
static int log_script(request_rec *r, cgi_server_conf * conf, int ret,
                      char *dbuf, const char *sbuf, apr_bucket_brigade *bb,
                      apr_file_t *script_err)
{
    const apr_array_header_t *hdrs_arr = apr_table_elts(r->headers_in);
    const apr_table_entry_t *hdrs = (const apr_table_entry_t *) hdrs_arr->elts;
    char argsbuffer[HUGE_STRING_LEN];
    apr_file_t *f = NULL;
    apr_bucket *e;
    const char *buf;
    apr_size_t len;
    apr_status_t rv;
    int first;
    int i;
    apr_finfo_t finfo;
    char time_str[APR_CTIME_LEN];

    /* XXX Very expensive mainline case! Open, then getfileinfo! */
    if (!conf->logname ||
        ((apr_stat(&finfo, conf->logname,
                   APR_FINFO_SIZE, r->pool) == APR_SUCCESS) &&
         (finfo.size > conf->logbytes)) ||
        (apr_file_open(&f, conf->logname,
                       APR_APPEND|APR_WRITE|APR_CREATE, APR_OS_DEFAULT,
                       r->pool) != APR_SUCCESS)) {
        /* Soak up script output */
        discard_script_output(bb);
        log_script_err(r, script_err);
        return ret;
    }

    /* "%% [Wed Jun 19 10:53:21 1996] GET /cgi-bin/printenv HTTP/1.0" */
    apr_ctime(time_str, apr_time_now());
    apr_file_printf(f, "%%%% [%s] %s %s%s%s %s\n", time_str, r->method, r->uri,
                    r->args ? "?" : "", r->args ? r->args : "", r->protocol);
    /* "%% 500 /usr/local/apache/cgi-bin" */
    apr_file_printf(f, "%%%% %d %s\n", ret, r->filename);

    apr_file_puts("%request\n", f);
    for (i = 0; i < hdrs_arr->nelts; ++i) {
        if (!hdrs[i].key)
            continue;
        apr_file_printf(f, "%s: %s\n", hdrs[i].key, hdrs[i].val);
    }
    if ((r->method_number == M_POST || r->method_number == M_PUT) &&
        *dbuf) {
        apr_file_printf(f, "\n%s\n", dbuf);
    }

    apr_file_puts("%response\n", f);
    hdrs_arr = apr_table_elts(r->err_headers_out);
    hdrs = (const apr_table_entry_t *) hdrs_arr->elts;

    for (i = 0; i < hdrs_arr->nelts; ++i) {
        if (!hdrs[i].key)
            continue;
        apr_file_printf(f, "%s: %s\n", hdrs[i].key, hdrs[i].val);
    }

    if (sbuf && *sbuf)
        apr_file_printf(f, "%s\n", sbuf);

    first = 1;
    for (e = APR_BRIGADE_FIRST(bb);
         e != APR_BRIGADE_SENTINEL(bb);
         e = APR_BUCKET_NEXT(e))
    {
        if (APR_BUCKET_IS_EOS(e)) {
            break;
        }
        rv = apr_bucket_read(e, &buf, &len, APR_BLOCK_READ);
        if (rv != APR_SUCCESS || (len == 0)) {
            break;
        }
        if (first) {
            apr_file_puts("%stdout\n", f);
            first = 0;
        }
        apr_file_write(f, buf, &len);
        apr_file_puts("\n", f);
    }

    if (apr_file_gets(argsbuffer, HUGE_STRING_LEN, script_err) == APR_SUCCESS) {
        apr_file_puts("%stderr\n", f);
        apr_file_puts(argsbuffer, f);
        while (apr_file_gets(argsbuffer, HUGE_STRING_LEN,
                             script_err) == APR_SUCCESS) {
            apr_file_puts(argsbuffer, f);
        }
        apr_file_puts("\n", f);
    }

    apr_brigade_destroy(bb);
    apr_file_close(script_err);

    apr_file_close(f);
    return ret;
}
Exemplo n.º 12
0
/* This implements the svn_client_list_func_t API, printing a single
   directory entry in text format. */
static svn_error_t *
print_dirent(void *baton,
             const char *path,
             const svn_dirent_t *dirent,
             const svn_lock_t *lock,
             const char *abs_path,
             apr_pool_t *pool)
{
  struct print_baton *pb = baton;
  const char *entryname;

  if (pb->ctx->cancel_func)
    SVN_ERR(pb->ctx->cancel_func(pb->ctx->cancel_baton));

  if (strcmp(path, "") == 0)
    {
      if (dirent->kind == svn_node_file)
        entryname = svn_dirent_basename(abs_path, pool);
      else if (pb->verbose)
        entryname = ".";
      else
        /* Don't bother to list if no useful information will be shown. */
        return SVN_NO_ERROR;
    }
  else
    entryname = path;

  if (pb->verbose)
    {
      apr_time_t now = apr_time_now();
      apr_time_exp_t exp_time;
      apr_status_t apr_err;
      apr_size_t size;
      char timestr[20];
      const char *sizestr, *utf8_timestr;

      /* svn_time_to_human_cstring gives us something *way* too long
         to use for this, so we have to roll our own.  We include
         the year if the entry's time is not within half a year. */
      apr_time_exp_lt(&exp_time, dirent->time);
      if (apr_time_sec(now - dirent->time) < (365 * 86400 / 2)
          && apr_time_sec(dirent->time - now) < (365 * 86400 / 2))
        {
          apr_err = apr_strftime(timestr, &size, sizeof(timestr),
                                 _("%b %d %H:%M"), &exp_time);
        }
      else
        {
          apr_err = apr_strftime(timestr, &size, sizeof(timestr),
                                 _("%b %d  %Y"), &exp_time);
        }

      /* if that failed, just zero out the string and print nothing */
      if (apr_err)
        timestr[0] = '\0';

      /* we need it in UTF-8. */
      SVN_ERR(svn_utf_cstring_to_utf8(&utf8_timestr, timestr, pool));

      sizestr = apr_psprintf(pool, "%" SVN_FILESIZE_T_FMT, dirent->size);

      return svn_cmdline_printf
              (pool, "%7ld %-8.8s %c %10s %12s %s%s\n",
               dirent->created_rev,
               dirent->last_author ? dirent->last_author : " ? ",
               lock ? 'O' : ' ',
               (dirent->kind == svn_node_file) ? sizestr : "",
               utf8_timestr,
               entryname,
               (dirent->kind == svn_node_dir) ? "/" : "");
    }
  else
    {
      return svn_cmdline_printf(pool, "%s%s\n", entryname,
                                (dirent->kind == svn_node_dir)
                                ? "/" : "");
    }
}
Exemplo n.º 13
0
/*--------------------------------------------------------------------------*/
static void* APR_THREAD_FUNC wd_worker(apr_thread_t *thread, void *data)
{
    ap_watchdog_t *w = (ap_watchdog_t *)data;
    apr_status_t rv;
    int locked = 0;
    int probed = 0;
    int inited = 0;
    int mpmq_s = 0;

    w->pool = apr_thread_pool_get(thread);
    w->is_running = 1;

    apr_thread_mutex_unlock(w->startup);
    if (w->mutex) {
        while (w->is_running) {
            if (ap_mpm_query(AP_MPMQ_MPM_STATE, &mpmq_s) != APR_SUCCESS) {
                w->is_running = 0;
                break;
            }
            if (mpmq_s == AP_MPMQ_STOPPING) {
                w->is_running = 0;
                break;
            }
            rv = apr_proc_mutex_trylock(w->mutex);
            if (rv == APR_SUCCESS) {
                if (probed) {
                    /* Sleep after we were locked
                     * up to 1 second. Httpd can be
                     * in the middle of shutdown, and
                     * our child didn't yet received
                     * the shutdown signal.
                     */
                    probed = 10;
                    while (w->is_running && probed > 0) {
                        apr_sleep(AP_WD_TM_INTERVAL);
                        probed--;
                        if (ap_mpm_query(AP_MPMQ_MPM_STATE, &mpmq_s) != APR_SUCCESS) {
                            w->is_running = 0;
                            break;
                        }
                        if (mpmq_s == AP_MPMQ_STOPPING) {
                            w->is_running = 0;
                            break;
                        }
                    }
                }
                locked = 1;
                break;
            }
            probed = 1;
            apr_sleep(AP_WD_TM_SLICE);
        }
    }
    if (w->is_running) {
        watchdog_list_t *wl = w->callbacks;
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, wd_server_conf->s,
                     APLOGNO(02972) "%sWatchdog (%s) running",
                     w->singleton ? "Singleton " : "", w->name);
        apr_time_clock_hires(w->pool);
        if (wl) {
            apr_pool_t *ctx = NULL;
            apr_pool_create(&ctx, w->pool);
            while (wl && w->is_running) {
                /* Execute watchdog callback */
                wl->status = (*wl->callback_fn)(AP_WATCHDOG_STATE_STARTING,
                                                (void *)wl->data, ctx);
                wl = wl->next;
            }
            apr_pool_destroy(ctx);
        }
        else {
            ap_run_watchdog_init(wd_server_conf->s, w->name, w->pool);
            inited = 1;
        }
    }

    /* Main execution loop */
    while (w->is_running) {
        apr_pool_t *ctx = NULL;
        apr_time_t curr;
        watchdog_list_t *wl = w->callbacks;

        apr_sleep(AP_WD_TM_SLICE);
        if (ap_mpm_query(AP_MPMQ_MPM_STATE, &mpmq_s) != APR_SUCCESS) {
            w->is_running = 0;
        }
        if (mpmq_s == AP_MPMQ_STOPPING) {
            w->is_running = 0;
        }
        if (!w->is_running) {
            break;
        }
        curr = apr_time_now() - AP_WD_TM_SLICE;
        while (wl && w->is_running) {
            if (wl->status == APR_SUCCESS) {
                wl->step += (apr_time_now() - curr);
                if (wl->step >= wl->interval) {
                    if (!ctx)
                        apr_pool_create(&ctx, w->pool);
                    wl->step = 0;
                    /* Execute watchdog callback */
                    wl->status = (*wl->callback_fn)(AP_WATCHDOG_STATE_RUNNING,
                                                    (void *)wl->data, ctx);
                    if (ap_mpm_query(AP_MPMQ_MPM_STATE, &mpmq_s) != APR_SUCCESS) {
                        w->is_running = 0;
                    }
                    if (mpmq_s == AP_MPMQ_STOPPING) {
                        w->is_running = 0;
                    }
                }
            }
            wl = wl->next;
        }
        if (w->is_running && w->callbacks == NULL) {
            /* This is hook mode watchdog
             * running on WatchogInterval
             */
            w->step += (apr_time_now() - curr);
            if (w->step >= wd_interval) {
                if (!ctx)
                    apr_pool_create(&ctx, w->pool);
                w->step = 0;
                /* Run watchdog step hook */
                ap_run_watchdog_step(wd_server_conf->s, w->name, ctx);
            }
        }
        if (ctx)
            apr_pool_destroy(ctx);
        if (!w->is_running) {
            break;
        }
    }
    if (inited) {
        /* Run the watchdog exit hooks.
         * If this was singleton watchdog the init hook
         * might never been called, so skip the exit hook
         * in that case as well.
         */
        ap_run_watchdog_exit(wd_server_conf->s, w->name, w->pool);
    }
    else {
        watchdog_list_t *wl = w->callbacks;
        while (wl) {
            if (wl->status == APR_SUCCESS) {
                /* Execute watchdog callback with STOPPING state */
                (*wl->callback_fn)(AP_WATCHDOG_STATE_STOPPING,
                                   (void *)wl->data, w->pool);
            }
            wl = wl->next;
        }
    }
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, wd_server_conf->s,
                 APLOGNO(02973) "%sWatchdog (%s) stopping",
                 w->singleton ? "Singleton " : "", w->name);

    if (locked)
        apr_proc_mutex_unlock(w->mutex);
    apr_thread_exit(w->thread, APR_SUCCESS);

    return NULL;
}
Exemplo n.º 14
0
/* Main processing of the parent process
 * returns TRUE if restarting
 */
static char master_main()
{
    server_rec *s = ap_server_conf;
    ap_listen_rec *lr;
    parent_info_t *parent_info;
    char *listener_shm_name;
    int listener_num, num_listeners, slot;
    ULONG rc;

    printf("%s \n", ap_get_server_version());
    set_signals();

    if (ap_setup_listeners(ap_server_conf) < 1) {
        ap_log_error(APLOG_MARK, APLOG_ALERT, 0, s,
                     "no listening sockets available, shutting down");
        return FALSE;
    }

    /* Allocate a shared memory block for the array of listeners */
    for (num_listeners = 0, lr = ap_listeners; lr; lr = lr->next) {
        num_listeners++;
    }

    listener_shm_name = apr_psprintf(pconf, "/sharemem/httpd/parent_info.%d", getpid());
    rc = DosAllocSharedMem((PPVOID)&parent_info, listener_shm_name,
                           sizeof(parent_info_t) + num_listeners * sizeof(listen_socket_t),
                           PAG_READ|PAG_WRITE|PAG_COMMIT);

    if (rc) {
        ap_log_error(APLOG_MARK, APLOG_ALERT, APR_FROM_OS_ERROR(rc), s,
                     "failure allocating shared memory, shutting down");
        return FALSE;
    }

    /* Store the listener sockets in the shared memory area for our children to see */
    for (listener_num = 0, lr = ap_listeners; lr; lr = lr->next, listener_num++) {
        apr_os_sock_get(&parent_info->listeners[listener_num].listen_fd, lr->sd);
    }

    /* Create mutex to prevent multiple child processes from detecting
     * a connection with apr_poll()
     */

    rc = DosCreateMutexSem(NULL, &ap_mpm_accept_mutex, DC_SEM_SHARED, FALSE);

    if (rc) {
        ap_log_error(APLOG_MARK, APLOG_ALERT, APR_FROM_OS_ERROR(rc), s,
                     "failure creating accept mutex, shutting down");
        return FALSE;
    }

    parent_info->accept_mutex = ap_mpm_accept_mutex;

    /* Allocate shared memory for scoreboard */
    if (ap_scoreboard_image == NULL) {
        void *sb_mem;
        rc = DosAllocSharedMem(&sb_mem, ap_scoreboard_fname,
                               ap_calc_scoreboard_size(),
                               PAG_COMMIT|PAG_READ|PAG_WRITE);

        if (rc) {
            ap_log_error(APLOG_MARK, APLOG_ERR, APR_FROM_OS_ERROR(rc), ap_server_conf,
                         "unable to allocate shared memory for scoreboard , exiting");
            return FALSE;
        }

        ap_init_scoreboard(sb_mem);
    }

    ap_scoreboard_image->global->restart_time = apr_time_now();
    ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf,
		"%s configured -- resuming normal operations",
		ap_get_server_version());
    ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf,
		"Server built: %s", ap_get_server_built());
#ifdef AP_MPM_WANT_SET_ACCEPT_LOCK_MECH
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
		"AcceptMutex: %s (default: %s)",
		apr_proc_mutex_name(accept_mutex),
		apr_proc_mutex_defname());
#endif
    if (one_process) {
        ap_scoreboard_image->parent[0].pid = getpid();
        ap_mpm_child_main(pconf);
        return FALSE;
    }

    while (!restart_pending && !shutdown_pending) {
        RESULTCODES proc_rc;
        PID child_pid;
        int active_children = 0;

        /* Count number of active children */
        for (slot=0; slot < HARD_SERVER_LIMIT; slot++) {
            active_children += ap_scoreboard_image->parent[slot].pid != 0 &&
                !ap_scoreboard_image->parent[slot].quiescing;
        }

        /* Spawn children if needed */
        for (slot=0; slot < HARD_SERVER_LIMIT && active_children < ap_daemons_to_start; slot++) {
            if (ap_scoreboard_image->parent[slot].pid == 0) {
                spawn_child(slot);
                active_children++;
            }
        }

        rc = DosWaitChild(DCWA_PROCESSTREE, DCWW_NOWAIT, &proc_rc, &child_pid, 0);

        if (rc == 0) {
            /* A child has terminated, remove its scoreboard entry & terminate if necessary */
            for (slot=0; ap_scoreboard_image->parent[slot].pid != child_pid && slot < HARD_SERVER_LIMIT; slot++);

            if (slot < HARD_SERVER_LIMIT) {
                ap_scoreboard_image->parent[slot].pid = 0;
                ap_scoreboard_image->parent[slot].quiescing = 0;

                if (proc_rc.codeTerminate == TC_EXIT) {
                    /* Child terminated normally, check its exit code and
                     * terminate server if child indicates a fatal error
                     */
                    if (proc_rc.codeResult == APEXIT_CHILDFATAL)
                        break;
                }
            }
        } else if (rc == ERROR_CHILD_NOT_COMPLETE) {
            /* No child exited, lets sleep for a while.... */
            apr_sleep(SCOREBOARD_MAINTENANCE_INTERVAL);
        }
    }

    /* Signal children to shut down, either gracefully or immediately */
    for (slot=0; slot<HARD_SERVER_LIMIT; slot++) {
      kill(ap_scoreboard_image->parent[slot].pid, is_graceful ? SIGHUP : SIGTERM);
    }

    DosFreeMem(parent_info);
    return restart_pending;
}
Exemplo n.º 15
0
mapcache_http_response *mapcache_core_get_map(mapcache_context *ctx, mapcache_request_get_map *req_map)
{
  mapcache_image_format *format = NULL;
  mapcache_http_response *response;
  mapcache_map *basemap = NULL;
  char *timestr;
#ifdef DEBUG
  if(req_map->nmaps ==0) {
    ctx->set_error(ctx,500,"BUG: get_map called with 0 maps");
    return NULL;
  }
#endif


  if(req_map->getmap_strategy == MAPCACHE_GETMAP_ERROR) {
    ctx->set_error(ctx, 404, "full wms support disabled");
    return NULL;
  }

  format = NULL;
  response = mapcache_http_response_create(ctx->pool);


  if(req_map->getmap_strategy == MAPCACHE_GETMAP_ASSEMBLE) {
    basemap = mapcache_assemble_maps(ctx, req_map->maps, req_map->nmaps, req_map->resample_mode);
    if(GC_HAS_ERROR(ctx)) return NULL;
  } else if(!ctx->config->non_blocking && req_map->getmap_strategy == MAPCACHE_GETMAP_FORWARD) {
    int i;
    basemap = req_map->maps[0];
    for(i=0; i<req_map->nmaps; i++) {
      if(!req_map->maps[i]->tileset->source) {
        ctx->set_error(ctx,404,"cannot forward request for tileset %s: no source configured",
                       req_map->maps[i]->tileset->name);
        return NULL;
      }
    }
    basemap->tileset->source->render_map(ctx, basemap);
    if(GC_HAS_ERROR(ctx)) return NULL;
    if(req_map->nmaps>1) {
      if(!basemap->raw_image) {
        basemap->raw_image = mapcache_imageio_decode(ctx,basemap->encoded_data);
        if(GC_HAS_ERROR(ctx)) return NULL;
      }
      for(i=1; i<req_map->nmaps; i++) {
        mapcache_map *overlaymap = req_map->maps[i];
        overlaymap->tileset->source->render_map(ctx, overlaymap);
        if(GC_HAS_ERROR(ctx)) return NULL;
        if(!overlaymap->raw_image) {
          overlaymap->raw_image = mapcache_imageio_decode(ctx,overlaymap->encoded_data);
          if(GC_HAS_ERROR(ctx)) return NULL;
        }
        if(GC_HAS_ERROR(ctx)) return NULL;
        mapcache_image_merge(ctx,basemap->raw_image,overlaymap->raw_image);
        if(GC_HAS_ERROR(ctx)) return NULL;
        if(!basemap->expires || overlaymap->expires<basemap->expires) basemap->expires = overlaymap->expires;
      }
    }
  } else {
    ctx->set_error(ctx,400,"failed getmap, readonly mode");
    return NULL;
  }

  if(basemap->raw_image) {
    format = req_map->getmap_format; /* always defined, defaults to JPEG */
    response->data = format->write(ctx,basemap->raw_image,format);
    if(GC_HAS_ERROR(ctx)) {
      return NULL;
    }
  } else {
    /* this case happens when we have a forward strategy for a single tileset */
#ifdef DEBUG
    if(!basemap->encoded_data) {
      ctx->set_error(ctx,500,"###BUG### core_get_map failed with null encoded_data");
      return NULL;
    }
#endif
    response->data = basemap->encoded_data;
  }

  /* compute the content-type */
  if(format && format->mime_type) {
    apr_table_set(response->headers,"Content-Type",format->mime_type);
  } else {
    mapcache_image_format_type t = mapcache_imageio_header_sniff(ctx,response->data);
    if(t == GC_PNG)
      apr_table_set(response->headers,"Content-Type","image/png");
    else if(t == GC_JPEG)
      apr_table_set(response->headers,"Content-Type","image/jpeg");
  }

  /* compute expiry headers */
  if(basemap->expires) {
    apr_time_t now = apr_time_now();
    apr_time_t additional = apr_time_from_sec(basemap->expires);
    apr_time_t texpires = now + additional;
    apr_table_set(response->headers, "Cache-Control",
                  apr_psprintf(ctx->pool, "max-age=%d", basemap->expires));
    timestr = apr_palloc(ctx->pool, APR_RFC822_DATE_LEN);
    apr_rfc822_date(timestr, texpires);
    apr_table_setn(response->headers, "Expires", timestr);
  }

  response->mtime = basemap->mtime;
  return response;
}
Exemplo n.º 16
0
static apr_status_t modsecurity_process_phase_logging(modsec_rec *msr) 
{
    apr_time_t time_before, time_after;
    
    if (msr->txcfg->debuglog_level >= 4) {
        msr_log(msr, 4, "Starting phase LOGGING.");
    }
    
    time_before = apr_time_now();

    if (msr->txcfg->ruleset != NULL) {
        msre_ruleset_process_phase(msr->txcfg->ruleset, msr);
    }
    
    modsecurity_persist_data(msr);
    
    time_after = apr_time_now();
    msr->time_phase5 = time_after - time_before;

    /* Is this request relevant for logging purposes? */
#if 0
    if (msr->is_relevant == 0) {
        /* Check the status */
        msr->is_relevant += is_response_status_relevant(msr, msr->r->status);

        /* If we processed two requests and statuses are different then check the other status too. */
        if (msr->r_early->status != msr->r->status) {
            msr->is_relevant += is_response_status_relevant(msr, msr->r_early->status);
        }

    }
#endif

    /* Figure out if we want to keep the files (if there are any, of course). */
    if ((msr->txcfg->upload_keep_files == KEEP_FILES_ON) || 
        ((msr->txcfg->upload_keep_files == KEEP_FILES_RELEVANT_ONLY) && (msr->is_relevant))) {
        msr->upload_remove_files = 0;
    } else {
        msr->upload_remove_files = 1;
    }

    /* Are we configured for audit logging? */
    switch(msr->txcfg->attacklog_flag) {
    case AUDITLOG_OFF :
        if (msr->txcfg->debuglog_level >= 4) {
            msr_log(msr, 4, "Audit log: Not configured to run for this request.");
        }
        return DECLINED;
        break;
/* 裁减 */
#if 0
    case AUDITLOG_RELEVANT :
        if (msr->is_relevant == 0) {
            if (msr->txcfg->debuglog_level >= 4) {
                msr_log(msr, 4, "Audit log: Ignoring a non-relevant request.");
            }            
            return DECLINED;
        }
        break;
#endif
    case AUDITLOG_ON :
        /* All right, do nothing */
        break;

    default :
        msr_log(msr, 1, "Internal error: Could not determine if auditing is needed, so forcing auditing.");
        break;
    }

    /* Invoke the Audit logger */
    if (msr->txcfg->debuglog_level >= 4) {
        msr_log(msr, 4, "Audit log: Logging this transaction.");
    }

    /* sec_attack_logger(msr); 该函数移至外面 */
    
    msr->time_logging = apr_time_now() - time_after;    

    return 0;
}
Exemplo n.º 17
0
IDATA monitor_wait_impl(hythread_monitor_t mon_ptr, I_64 ms, IDATA nano, IDATA interruptable) {
    IDATA status;
    int saved_recursion;
    //int saved_disable_count;
    hythread_t self = tm_self_tls;
    if (mon_ptr->owner != self) {
        return TM_ERROR_ILLEGAL_STATE;
    }

    saved_recursion = mon_ptr->recursion_count;

    assert(saved_recursion>=0);

    mon_ptr->owner = NULL;
    mon_ptr->recursion_count =0;
    mon_ptr->wait_count++;
    port_mutex_lock(&self->mutex);
    self->state |= TM_THREAD_STATE_IN_MONITOR_WAIT;
    self->waited_monitor = mon_ptr;
    port_mutex_unlock(&self->mutex);

    do {
        apr_time_t start;
        assert(mon_ptr->notify_count >= 0);
        assert(mon_ptr->notify_count < mon_ptr->wait_count);
        start = apr_time_now();
        status = condvar_wait_impl(&mon_ptr->condition, &mon_ptr->mutex, ms, nano, interruptable);
        if (status != TM_ERROR_NONE || mon_ptr->notify_count) {
            break;
        }
        // we should not change ms and nano if both are 0 (meaning "no timeout")
        if (ms || nano) {
            apr_interval_time_t elapsed;
            elapsed = apr_time_now() - start; // microseconds
            nano -= (IDATA)((elapsed % 1000) * 1000);
            if (nano < 0) {
                ms -= elapsed/1000 + 1;
                nano += 1000000;
            } else {
                ms -= elapsed/1000;
            }
            if (ms < 0) {
                assert(status == TM_ERROR_NONE);
                status = TM_ERROR_TIMEOUT;
                break;
            }
            assert(0 <= nano && nano < 1000000);
        }
    } while (1);

    // consume the notify_count unless we got an error (or were interrupted)
    if (mon_ptr->notify_count > 0
        && (status == TM_ERROR_NONE || mon_ptr->notify_count == mon_ptr->wait_count))
    {
        mon_ptr->notify_count--;
    }

    port_mutex_lock(&self->mutex);
    self->state &= ~TM_THREAD_STATE_IN_MONITOR_WAIT;
    self->waited_monitor = NULL;
    port_mutex_unlock(&self->mutex);

    mon_ptr->wait_count--;
    assert(mon_ptr->notify_count <= mon_ptr->wait_count);

    if (self->request) {
        int save_count;
        port_mutex_unlock(&mon_ptr->mutex);
        hythread_safe_point();
        hythread_exception_safe_point();
        save_count = hythread_reset_suspend_disable();
        port_mutex_lock(&mon_ptr->mutex);
        hythread_set_suspend_disable(save_count);
    }

    mon_ptr->recursion_count = saved_recursion;
    mon_ptr->owner = self;
    assert(mon_ptr->owner);
    return status;
}
Exemplo n.º 18
0
/**
 * record attack log on in temporary buffer msr->auditlogs and make the sql statement format.
 */
void msc_record_attacklog(modsec_rec *msr, msre_var *var, msre_actionset *actionset)
{
    int i;
    msre_action *action;
    const apr_array_header_t *tarr = NULL;
    const apr_table_entry_t *telts = NULL;
    const char *cliip;
    unsigned int cliport;
    const char *serip;
    unsigned int serport;
    const char *url;
    const char *method;
    const char *protocol;
    const char *attname;
    const char *clios;
    const char *clibrowser;
    int action_id;
    int severity_id;
    char *attdomain;
    char *sql_statement = NULL;
    char *sql_statement_temp = NULL;
    char *msg = NULL;
    char country[256] = { 0 };
    char province[256] = { 0 };
    char city[256] = { 0 };
    char isp_gbk[512] = { 0 };    
    char *isp_utf8;
    const char *rule_id;
    int rv;
    const char *host;

    if (actionset ? (actionset->severity > msr->txcfg->attacklog_level ? 1 : 0) : 0) {
        return;
    }

    attname = "";
    attdomain = "";
    action_id = 0; 
    severity_id = 0;
    rule_id = "0";
    cliip = msr->remote_addr;
    cliport = msr->remote_port;
    serip = msr->local_addr;
    serport = msr->local_port;
    method = msr->request_method;
    clibrowser = ap_get_client_browser(msr->mp, msr->r);
    clios = ap_get_client_os(msr->mp, msr->r);  
    host = apr_table_get(msr->r->headers_in, "Host");
    url = apr_pstrcat(msr->mp, msr->hostname, msr->r->uri, msr->r->args ? "?" : "", 
                    msr->r->args, NULL);
    protocol = msr->request_protocol;
    if (protocol && !strcmp(protocol, "HTTP/0.9")) {
        url = "/";
        method = "GET";
        host = "";
    }
    
    if (actionset) {
        action_id = actionset->intercept_action;
        severity_id = actionset->severity;
        if (severity_id < 0 || severity_id > 7) {
            return;
        }
        
        /* 获取攻击名称 */
        tarr = apr_table_elts(actionset->actions);
        telts = (const apr_table_entry_t*)tarr->elts;
        for (i = 0; i < tarr->nelts; i++) {
            action = (msre_action *)telts[i].val;
            if (strcmp("tag", action->metadata->name) != 0) {
                continue;
            }
            if ((attname = action->param) == NULL) {
                return ;
            }
        }

        /* 获取攻击域 */           
        attdomain = get_attack_domain(var, method);
        if ((msg = (char *)actionset->msg) == NULL) {
            return;
        }
        if ((rule_id = actionset->id) == NULL) {
            return;
        }
    }

    /* 地理信息提取 */
    ap_ip_get_country(g_ip_location, cliip, country, 256);
    ap_ip_get_province(g_ip_location, cliip, province, 256);
    ap_ip_get_city(g_ip_location, cliip, city, 256);
    ap_ip_get_isp(g_ip_location, cliip, isp_gbk, 512);
    isp_utf8 = ap_convert_all_to_utf8(msr->mp, isp_gbk, "GB2312");   
    if (!isp_utf8 || (isp_utf8 && !strcmp(isp_utf8, ""))) {
        /* 未知isp */
        isp_utf8 = "\xE6\x9C\xAA\xE7\x9F\xA5";
    }
  
    /* 数据库SQL语句 */
    if (!msr->black_list_flag) {          /* 规则攻击日志 */
        sql_statement = apr_psprintf(msr->mp, INSERT_ATTACKLOG_TABLE_SQL, 
            (apr_int64_t)apr_time_sec(apr_time_now()),
            cliip ? dbd_escape(ap_logdb_driver, msr->mp, cliip, ap_logdb_handle) : "", 
            cliport, 
            serip ? dbd_escape(ap_logdb_driver, msr->mp, serip, ap_logdb_handle) : "", 
            serport, 
            apr_socket_get_offline_mode() ?  actions[5] : (actions[action_id] ? actions[action_id] : ""),
            severities[severity_id] ? severities[severity_id] : "", 
            method ? dbd_escape(ap_logdb_driver, msr->mp, method, ap_logdb_handle) : "", 
            attname ? dbd_escape(ap_logdb_driver, msr->mp, attname, ap_logdb_handle) : "", 
            attdomain ? dbd_escape(ap_logdb_driver, msr->mp, attdomain, ap_logdb_handle) : "", 
            protocol ? dbd_escape(ap_logdb_driver, msr->mp, protocol, ap_logdb_handle) :"", 
            msg ? dbd_escape(ap_logdb_driver, msr->mp, msg, ap_logdb_handle) : "",
            url ? dbd_escape(ap_logdb_driver, msr->mp, url, ap_logdb_handle) : "",
            clios ? dbd_escape(ap_logdb_driver, msr->mp, clios, ap_logdb_handle) : "",
            clibrowser ? dbd_escape(ap_logdb_driver, msr->mp, clibrowser, ap_logdb_handle) : "",
            dbd_escape(ap_logdb_driver, msr->mp, country, ap_logdb_handle),
            dbd_escape(ap_logdb_driver, msr->mp, province, ap_logdb_handle),
            dbd_escape(ap_logdb_driver, msr->mp, city, ap_logdb_handle),
            isp_utf8,
            rule_id,
            host ? dbd_escape(ap_logdb_driver, msr->mp, host, ap_logdb_handle) : (msr->r->hostname ? msr->r->hostname : "")
            );

        /* 用于攻击日志的实时监控 */
        sql_statement_temp = apr_psprintf(msr->mp, INSERT_ATTACKLOG_TABLE_SQL_TEMP, 
            (apr_int64_t)apr_time_sec(apr_time_now()),
            cliip ? dbd_escape(ap_logdb_driver, msr->mp, cliip, ap_logdb_handle) : "", 
            attname ? dbd_escape(ap_logdb_driver, msr->mp, attname, ap_logdb_handle) : "", 
            dbd_escape(ap_logdb_driver, msr->mp, country, ap_logdb_handle),
            dbd_escape(ap_logdb_driver, msr->mp, province, ap_logdb_handle),
            dbd_escape(ap_logdb_driver, msr->mp, city, ap_logdb_handle),
            isp_utf8
            );
    } else {                             /* 黑名单攻击日志 */
        if (msr->black_list_log) {
            msg = apr_psprintf(msr->mp, "%s%d", "attack times:", msr->black_list_hitcount);
            sql_statement = apr_psprintf(msr->mp, INSERT_ATTACKLOG_TABLE_SQL, 
                (apr_int64_t)apr_time_sec(apr_time_now()),
                cliip ? dbd_escape(ap_logdb_driver, msr->mp, cliip, ap_logdb_handle) : "", 
                cliport, 
                serip ? dbd_escape(ap_logdb_driver, msr->mp, serip, ap_logdb_handle) : "", 
                serport, 
                apr_socket_get_offline_mode() ?  actions[5] : (actions[1] ? actions[1] : ""),
                severities[0] ? severities[0] : "",   
                method ? dbd_escape(ap_logdb_driver, msr->mp, method, ap_logdb_handle) : "", 
                get_attack_string(msr), 
                dbd_escape(ap_logdb_driver, msr->mp, g_attack_domain[7], ap_logdb_handle),
                protocol ? dbd_escape(ap_logdb_driver, msr->mp, protocol, ap_logdb_handle) : "", 
                msg ? msg : "",
                url ? dbd_escape(ap_logdb_driver, msr->mp, url, ap_logdb_handle) : "",
                clios ? dbd_escape(ap_logdb_driver, msr->mp, clios, ap_logdb_handle) : "",
                clibrowser ? dbd_escape(ap_logdb_driver, msr->mp, clibrowser, ap_logdb_handle) : "",
                dbd_escape(ap_logdb_driver, msr->mp, country, ap_logdb_handle),
                dbd_escape(ap_logdb_driver, msr->mp, province, ap_logdb_handle),
                dbd_escape(ap_logdb_driver, msr->mp, city, ap_logdb_handle),
                isp_utf8,
                rule_id,
                host ? dbd_escape(ap_logdb_driver, msr->mp, host, ap_logdb_handle) : (msr->r->hostname ? msr->r->hostname : "")
                );
            
            /* 用于攻击日志的实时监控 */
            sql_statement_temp = apr_psprintf(msr->mp, INSERT_ATTACKLOG_TABLE_SQL_TEMP, 
                (apr_int64_t)apr_time_sec(apr_time_now()),
                cliip ? dbd_escape(ap_logdb_driver, msr->mp, cliip, ap_logdb_handle) : "", 
                get_attack_string(msr), 
                dbd_escape(ap_logdb_driver, msr->mp, country, ap_logdb_handle),
                dbd_escape(ap_logdb_driver, msr->mp, province, ap_logdb_handle),
                dbd_escape(ap_logdb_driver, msr->mp, city, ap_logdb_handle),   
                isp_utf8
                );
        } 
    }

    if (sql_statement) {
        *(const char **)apr_array_push(msr->attacklogs) = sql_statement;
    }

    if (sql_statement_temp) {
        rv = log_send(sql_statement_temp, 0);
        if (rv < 0) {
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "send temp attack log to log server failed.");
        }
    }    
}
Exemplo n.º 19
0
/*
 * check whether the provided string is a valid id_token and return its parsed contents
 */
apr_byte_t oidc_proto_parse_idtoken(request_rec *r, oidc_cfg *cfg,
		oidc_provider_t *provider, const char *id_token, const char *nonce,
		char **user, apr_jwt_t **jwt) {

	ap_log_rerror(APLOG_MARK, OIDC_DEBUG, 0, r,
			"oidc_proto_parse_idtoken: entering");

	if (apr_jwt_parse(r->pool, id_token, jwt, cfg->private_keys, provider->client_secret) == FALSE) {
		if ((*jwt) && ((*jwt)->header.alg)
				&& (apr_jwe_algorithm_is_supported(r->pool, (*jwt)->header.alg)
						== FALSE)) {
			ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
					"oidc_proto_parse_idtoken: JWE content key encryption algorithm is not supported: %s",
					(*jwt)->header.alg);
		}
		if ((*jwt) && ((*jwt)->header.enc)
				&& (apr_jwe_encryption_is_supported(r->pool, (*jwt)->header.enc)
						== FALSE)) {
			ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
					"oidc_proto_parse_idtoken: JWE encryption type is not supported: %s",
					(*jwt)->header.enc);
		}
		ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
				"oidc_proto_parse_idtoken: apr_jwt_parse failed for JWT with header: \"%s\"", apr_jwt_header_to_string(r->pool, id_token));
		apr_jwt_destroy(*jwt);
		return FALSE;
	}

	ap_log_rerror(APLOG_MARK, OIDC_DEBUG, 0, r,
			"oidc_proto_parse_idtoken: successfully parsed (and possibly decrypted) JWT with header: \"%s\"", apr_jwt_header_to_string(r->pool, id_token));

	// TODO: make signature validation exception for 'code' flow and the algorithm NONE
	apr_byte_t refresh = FALSE;
	if (oidc_proto_idtoken_verify_signature(r, cfg, provider, *jwt,
			&refresh) == FALSE) {
		ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
				"oidc_proto_parse_idtoken: id_token signature could not be validated, aborting");
		apr_jwt_destroy(*jwt);
		return FALSE;
	}

	/* this is where the meat is */
	if (oidc_proto_validate_idtoken(r, provider, *jwt, nonce) == FALSE) {
		ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
				"oidc_proto_parse_idtoken: id_token payload could not be validated, aborting");
		apr_jwt_destroy(*jwt);
		return FALSE;
	}

	if (oidc_proto_set_remote_user(r, cfg, provider, *jwt, user) == FALSE) {
		ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
				"oidc_proto_parse_idtoken: remote user could not be set, aborting");
		apr_jwt_destroy(*jwt);
		return FALSE;
	}

	/* log our results */
	ap_log_rerror(APLOG_MARK, OIDC_DEBUG, 0, r,
			"oidc_proto_parse_idtoken: valid id_token for user \"%s\" (expires in %" APR_TIME_T_FMT " seconds)",
			*user, (*jwt)->payload.exp - apr_time_sec(apr_time_now()));

	/* since we've made it so far, we may as well say it is a valid id_token */
	return TRUE;
}
Exemplo n.º 20
0
apr_status_t ma_advertise_server(server_rec *server, int type)
{
    char buf[MA_BSIZE];
    char dat[APR_RFC822_DATE_LEN];
    char add[40];
    unsigned char msig[APR_MD5_DIGESTSIZE];
    unsigned char ssig[APR_MD5_DIGESTSIZE * 2 + 1];
    const char *asl;
    char *p = buf;
    int  i, c = 0;
    apr_size_t l = MA_BSIZE - 8;
    apr_size_t n = 0;
    apr_md5_ctx_t md;
    mod_advertise_config *mconf = ap_get_module_config(server->module_config, &advertise_module);

    ma_sequence++;
    if (ma_sequence < 1)
        ma_sequence = 1;
    sprintf(buf, "%" APR_INT64_T_FMT, ma_sequence);
    ap_recent_rfc822_date(dat, apr_time_now());
    asl = ap_get_status_line(ma_advertise_stat);

    /* Create MD5 digest
     * salt + date + sequence + srvid
     */
    apr_md5_init(&md);
    apr_md5_update(&md, magd->ssalt, APR_MD5_DIGESTSIZE);
    apr_md5_update(&md, dat, strlen(dat));
    apr_md5_update(&md, buf, strlen(buf));
    apr_md5_update(&md, magd->srvid + 1, strlen(magd->srvid) - 1);
    apr_md5_final(msig, &md);
    /* Convert MD5 digest to hex string */
    for (i = 0; i < APR_MD5_DIGESTSIZE; i++) {
        ssig[c++] = hex[msig[i] >> 4];
        ssig[c++] = hex[msig[i] & 0x0F];
    }
    ssig[c] = '\0';
    n = apr_snprintf(p, l, MA_ADVERTISE_SERVER_FMT,
                     asl, dat, ma_sequence, ssig, magd->srvid + 1);
    if (type == MA_ADVERTISE_SERVER) {
        char *ma_advertise_srvs = mconf->ma_advertise_srvs;
        if (strchr(ma_advertise_srvs, ':') != NULL) {
            apr_snprintf(add, 40, "[%s]", mconf->ma_advertise_srvs);
            ma_advertise_srvs = add;
        }
        l -= n;
        n += apr_snprintf(p + n, l,
                          "X-Manager-Address: %s:%u" CRLF
                          "X-Manager-Url: %s" CRLF
                          "X-Manager-Protocol: %s" CRLF
                          "X-Manager-Host: %s" CRLF,
                          ma_advertise_srvs,
                          mconf->ma_advertise_srvp,
                          mconf->ma_advertise_srvh,
                          mconf->ma_advertise_srvm,
                          server->server_hostname);

    }
    strcat(p, CRLF);
    n += 2;
    return apr_socket_sendto(ma_mgroup_socket,
                             ma_mgroup_sa, 0, buf, &n);
}
Exemplo n.º 21
0
static int
RRD_update_cached( char *rrd, const char *sum, const char *num, unsigned int process_time )
{
   apr_time_t now, start = apr_time_now();
   int *conn, c, r, off, l, to;
   char *cmd, *str, buf[1024];
   struct pollfd pfd[1];

#ifdef HAVE___THREAD
   conn = &rrdcached_conn;
#else
   conn = pthread_getspecific(&rrdcached_conn_key);
   if (conn == NULL)
      {
         conn = calloc(1, sizeof (*conn));
         pthread_setspecific(&rrdcached_conn_key, conn);
         *conn = 0;
      }
#endif

   c = *conn;
   if (c == 0)
      {
reconnect:
         c = socket(PF_INET, SOCK_STREAM, 0);
         if (c == -1)
            {
               err_sys("Unable to create rrdcached socket");
            }

         if (connect(c, &gmetad_config.rrdcached_address,
                  sizeof (gmetad_config.rrdcached_address)) == -1)
            {
               err_sys("Unable to connect to rrdcached at %s", gmetad_config.rrdcached_addrstr);
            }

         r = 1;
         if (ioctl(c, FIONBIO, &r))
            {
               err_sys("Unable to set socket non-blocking");
            }

         *conn = c;
      }

   cmd = calloc(1, strlen(rrd) + 128);
   if (num)
         sprintf(cmd, "UPDATE %s %u:%s:%s\n", rrd, process_time, sum, num);
   else
         sprintf(cmd, "UPDATE %s %u:%s\n", rrd, process_time, sum);

   l = strlen(cmd);
   off = 0;
   do
      {
         r = write(c, cmd + off, l - off);
         off += r;
      }
   while ((off < l) || (r == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)));

   if (r == -1)
      {
         if (errno == ECONNRESET || errno == EPIPE)
            {
               free(cmd);
               goto reconnect;
            }
         err_sys("Error writing command %s to rrdcached\n", cmd);
      }

   free(cmd);

   pfd[0].fd = c;
   pfd[0].events = POLLIN;
   pfd[0].revents = 0;
   off = 0;
   to = 0;
   l = -1;

   while (1)
      {
         int r = poll(pfd, 1, 250);
         
         if (r == 0)
            {
               to += 250;
               if (to >= 5000)
                  {
                     err_msg("Timed out reading from rrdcached");
                     break;
                  }
               continue;
            }
         else if (r == -1)
            {
               if (errno == EAGAIN)
                  {
                     pfd[0].events = POLLIN;
                     pfd[0].revents = 0;
                     continue;
                  }

               break;
            }
         else
            {
               if (pfd[0].revents & POLLERR || pfd[0].revents & POLLHUP)
                  {
                     /* Hack to avoid looping on a flappy socket */
                     to += 5000;
                     goto reconnect;
                  }

               r = read(c, buf, sizeof(buf));
               if (r == 0)
                  {
                     to += 5000;
                     goto reconnect;
                  }
               else if (r == -1)
                  {
                     err_msg("Error reading from rrdcached");
                     break;
                  }

               if (l == -1)
                  {
                     /*
                      * First character output is number of lines to follow.
                      * Search for that many lines in our buffer.
                      */
                     l = buf[0] - 29;
                  }

               str = buf;
               while (l > 0 && (str = memchr(str, '\n', strlen(str))) != NULL)
                  {
                     l--;
                  }

               /* We've read all the data. */
               if (l == 0)
                  {
                     break;
                  }
            }
      }

    now = apr_time_now();
    ganglia_scoreboard_incby(METS_ALL_DURATION, now - start);
    ganglia_scoreboard_incby(METS_RRDCACHED_DURATION, now - start);
   return 0;
}
Exemplo n.º 22
0
static apr_status_t setUserInDb(apr_dbm_t *userDbm,
                                const char *user,
                                const char *password,
                                yubiauth_dir_cfg *cfg,
                                request_rec *r)
{
    char *timeAuthenticated = NULL;
    char *dbToken = NULL; //This is used to store pw:date
    char *userKey = NULL;

    apr_datum_t key, value;
    apr_status_t rv;

    /* Built up some combination of token:time */
    timeAuthenticated = apr_psprintf(r->pool, "%" APR_TIME_T_FMT, (apr_time_t) (apr_time_sec(apr_time_now())));
    dbToken = apr_pstrcat(r->pool, password, ":", timeAuthenticated, NULL);

    /* store OTP:time combo with username as key in DB */
    userKey = getDbKey(user, cfg, r);
    key = string2datum(userKey, r);
    value = string2datum(dbToken, r);

    /* Pump user into db, store un, cookie value, creation date,
     * let this expire sometime
     */
    ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_DEBUG, 0, r, LOG_PREFIX "Writing key: %s and value: %s to db",
                  key.dptr, value.dptr);
    rv = apr_dbm_store(userDbm, key, value);
    if (rv != APR_SUCCESS) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, LOG_PREFIX "Error writing to db ... with key: %s and value: %s",
                      key.dptr, value.dptr);
    }
    /* Spit back, so we can decide wheather s.th. went wrong or not */
    return rv;
}
Exemplo n.º 23
0
/**
 * A h2_mplx needs to be thread-safe *and* if will be called by
 * the h2_session thread *and* the h2_worker threads. Therefore:
 * - calls are protected by a mutex lock, m->lock
 * - the pool needs its own allocator, since apr_allocator_t are 
 *   not re-entrant. The separate allocator works without a 
 *   separate lock since we already protect h2_mplx itself.
 *   Since HTTP/2 connections can be expected to live longer than
 *   their HTTP/1 cousins, the separate allocator seems to work better
 *   than protecting a shared h2_session one with an own lock.
 */
h2_mplx *h2_mplx_create(conn_rec *c, apr_pool_t *parent, 
                        const h2_config *conf, 
                        apr_interval_time_t stream_timeout,
                        h2_workers *workers)
{
    apr_status_t status = APR_SUCCESS;
    apr_allocator_t *allocator = NULL;
    h2_mplx *m;
    AP_DEBUG_ASSERT(conf);
    
    status = apr_allocator_create(&allocator);
    if (status != APR_SUCCESS) {
        return NULL;
    }

    m = apr_pcalloc(parent, sizeof(h2_mplx));
    if (m) {
        m->id = c->id;
        APR_RING_ELEM_INIT(m, link);
        m->c = c;
        apr_pool_create_ex(&m->pool, parent, NULL, allocator);
        if (!m->pool) {
            return NULL;
        }
        apr_pool_tag(m->pool, "h2_mplx");
        apr_allocator_owner_set(allocator, m->pool);
        
        status = apr_thread_mutex_create(&m->lock, APR_THREAD_MUTEX_DEFAULT,
                                         m->pool);
        if (status != APR_SUCCESS) {
            h2_mplx_destroy(m);
            return NULL;
        }
        
        status = apr_thread_cond_create(&m->task_thawed, m->pool);
        if (status != APR_SUCCESS) {
            h2_mplx_destroy(m);
            return NULL;
        }
    
        m->bucket_alloc = apr_bucket_alloc_create(m->pool);
        m->max_streams = h2_config_geti(conf, H2_CONF_MAX_STREAMS);
        m->stream_max_mem = h2_config_geti(conf, H2_CONF_STREAM_MAX_MEM);
        m->q = h2_iq_create(m->pool, m->max_streams);
        m->stream_ios = h2_io_set_create(m->pool);
        m->ready_ios = h2_io_set_create(m->pool);
        m->stream_timeout = stream_timeout;
        m->workers = workers;
        m->workers_max = workers->max_workers;
        m->workers_def_limit = 4;
        m->workers_limit = m->workers_def_limit;
        m->last_limit_change = m->last_idle_block = apr_time_now();
        m->limit_change_interval = apr_time_from_msec(200);
        
        m->tx_handles_reserved = 0;
        m->tx_chunk_size = 4;
        
        m->spare_slaves = apr_array_make(m->pool, 10, sizeof(conn_rec*));
        
        m->ngn_shed = h2_ngn_shed_create(m->pool, m->c, m->max_streams, 
                                         m->stream_max_mem);
        h2_ngn_shed_set_ctx(m->ngn_shed , m);
    }
    return m;
}
Exemplo n.º 24
0
Arquivo: opt.c Projeto: DJEX93/dsploit
/* Parse one revision specification.  Return pointer to character
   after revision, or NULL if the revision is invalid.  Modifies
   str, so make sure to pass a copy of anything precious.  Uses
   POOL for temporary allocation. */
static char *parse_one_rev(svn_opt_revision_t *revision, char *str,
                           apr_pool_t *pool)
{
  char *end, save;

  /* Allow any number of 'r's to prefix a revision number, because
     that way if a script pastes svn output into another svn command
     (like "svn log -r${REV_COPIED_FROM_OUTPUT}"), it'll Just Work,
     even when compounded.

     As it happens, none of our special revision words begins with
     "r".  If any ever do, then this code will have to get smarter.

     Incidentally, this allows "r{DATE}".  We could avoid that with
     some trivial code rearrangement, but it's not clear what would
     be gained by doing so. */
  while (*str == 'r')
    str++;

  if (*str == '{')
    {
      svn_boolean_t matched;
      apr_time_t tm;
      svn_error_t *err;

      /* Brackets denote a date. */
      str++;
      end = strchr(str, '}');
      if (!end)
        return NULL;
      *end = '\0';
      err = svn_parse_date(&matched, &tm, str, apr_time_now(), pool);
      if (err)
        {
          svn_error_clear(err);
          return NULL;
        }
      if (!matched)
        return NULL;
      revision->kind = svn_opt_revision_date;
      revision->value.date = tm;
      return end + 1;
    }
  else if (svn_ctype_isdigit(*str))
    {
      /* It's a number. */
      end = str + 1;
      while (svn_ctype_isdigit(*end))
        end++;
      save = *end;
      *end = '\0';
      revision->kind = svn_opt_revision_number;
      revision->value.number = SVN_STR_TO_REV(str);
      *end = save;
      return end;
    }
  else if (svn_ctype_isalpha(*str))
    {
      end = str + 1;
      while (svn_ctype_isalpha(*end))
        end++;
      save = *end;
      *end = '\0';
      if (revision_from_word(revision, str) != 0)
        return NULL;
      *end = save;
      return end;
    }
  else
    return NULL;
}
Exemplo n.º 25
0
/* return 0 means OK, return -1 means ERROR */
static int update_expired_data_from_remote_info (request_rec *r,
                                                 REMOTE_INFO *p_remote_info)
{
    apr_size_t len;
    char errmsg_buf[120];
    apr_pool_t *rp = r->pool;
    apr_time_t cur_time = apr_time_now ();
    int redirect_cnt;

    char *now_url = apr_pstrdup (rp, p_remote_info->remote_url);
    char *hostname;
    apr_int64_t port;
    char *filepath;
    
    apr_status_t rv;
    apr_socket_t *s;
    apr_sockaddr_t *sa;

    char *req_msg;
    char header[HEADER_SIZE + 10], redundant[HEADER_SIZE + 10];
    apr_size_t hlen, rlen;
    char *status_code;
    apr_size_t expect_len;
    char *content_type;
    char *file_content;
    apr_size_t flen;
    char *ts;

#ifdef DEBUG
    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "before loop");
#endif

    for (redirect_cnt = 0; redirect_cnt <= MAX_REDIRECT_TIME; redirect_cnt++) {

        if (parse_url (r, now_url, &hostname, &port, &filepath) == -1) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                          "the module fail to get info from remote url,"
                          " remote url in configuration file may be invalid.");
#ifdef DEBUG
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
                          "fail to parse %s", now_url);
#endif
            return -1;
        }

#ifdef DEBUG
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "before build connection");
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
                      "hostname: %s | filepath: %s | port: %lld",
                      hostname, filepath, port);
#endif
            /* build connection */
        rv = build_connection (r, hostname, port, &s, &sa);
        if (rv != APR_SUCCESS) {
            apr_strerror (rv, errmsg_buf, sizeof (errmsg_buf));
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                          "connection error: %s", errmsg_buf);
            return -1;
        }

            /* set timeout */
        apr_socket_opt_set (s, APR_SO_NONBLOCK, 1);
        apr_socket_timeout_set (s, DEF_SOCK_TIMEOUT);

            /* send request */
        req_msg = apr_pstrcat(rp, "GET ", filepath, " HTTP/1.0", CRLF_STR,
                              "If-Modified-Since: ",
                              p_remote_info->last_update_time,
                              CRLF_STR, CRLF_STR, NULL);
        len = strlen (req_msg);
        rv = apr_socket_send (s, req_msg, &len);
        if (rv != APR_SUCCESS) {
            apr_strerror (rv, errmsg_buf, sizeof (errmsg_buf));
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                          "fail to send the request to url: %s", errmsg_buf);
            return -1;
        }

#ifdef DEBUG
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "before get header");
#endif
            /* get response header */
        hlen = rlen = HEADER_SIZE;
        if (get_header_from_response (r, s, header, &hlen, redundant, &rlen)
            == -1)
            return -1;

#ifdef DEBUG
        header[hlen] = '\0';
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "header: %s", header);
#endif

            /* get status code */
        if (get_status_code_from_header (r, header, hlen, &status_code) == -1)
            return -1;

#ifdef DEBUG
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
                      "status code: %s", status_code);
#endif
        
            /* deal with different status_code */
        if (strcmp (status_code, "200") == 0
            || (strcmp (status_code, "304") == 0
                && strcmp (now_url, p_remote_info->last_update_url) != 0)) {
                /* need to update */
            if (get_content_length_from_header
                (r, header, hlen, FILE_SIZE, &expect_len)
                == -1)
                return -1;

            if (get_content_type_from_header (r, header, hlen, &content_type)
                == -1)
                return -1;
#ifdef DEBUG
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
                          "Content-Type: %s", content_type);
#endif
            if (strncasecmp (content_type, "text", 4) != 0) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                              "the module fail to get info from "
                              "remote url, remote url in configuration"
                              " file may be invalid.");
                return -1;
            }
            
            file_content = apr_palloc (rp, expect_len + 2);
            if (get_body_from_response
                (r, s, expect_len, redundant, rlen, file_content, &flen)
                == -1)
                return -1;

#ifdef DEBUG
            file_content[flen] = '\0';
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
                          "file_content: %s", file_content);
#endif

                /* clear the pool, preventing leakage */
            apr_pool_clear (p_remote_info->subpool);
                /* update last_update_time */
            if (get_date_from_header (r, header, hlen, &ts) == -1) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "date unfound");
                p_remote_info->last_update_time = NULL;
            }
            else {
                p_remote_info->last_update_time =
                    apr_pstrdup (p_remote_info->subpool, ts);
            }
                /* update last_update_url */
            p_remote_info->last_update_url =
                apr_pstrdup (p_remote_info->subpool, now_url);
                /* get the ipsubnet_list from file_content*/
            file_content[flen] = '\n';
            get_ipsubnet_list_from_file_content (r,
                                                 p_remote_info->subpool,
                                                 file_content,
                                                 flen,
                                                 &(p_remote_info->p_ipsubnet_list));

            return 0;
        }
        else if (strcmp (status_code, "304") == 0) {/* not modified */
            return 0;
        }
        else if (strcmp (status_code, "300") == 0
                 || strcmp (status_code, "301") == 0
                 || strcmp (status_code, "302") == 0
                 || strcmp (status_code, "307") == 0) {/* redirect */
            if (get_location_from_header (r, header, hlen, &now_url) == -1) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                              "the module fail to get info"
                              " from remote url, remote url in "
                              "configuration file may be invalid.");
                return -1;
            }
            continue;
        }
        else {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                          "the module fail to get info"
                          " from remote url, remote url in "
                          "configuration file may be invalid.");
            return -1;
        }
    }

    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                  "the remote url redirects too many times,"
                  " auth_remote_module stop updating data from"
                  " url to prevent infinite redirection loop");
    return -1;
}
// Find the cookie and figure out what to do
static int spot_cookie(request_rec *r)
{
    cookietrack_settings_rec *dcfg = ap_get_module_config(r->per_dir_config,
                                                &cookietrack_module);

    const char *cookie_header;
    ap_regmatch_t regm[NUM_SUBS];

    /* Do not run in subrequests */
    if (!dcfg->enabled || r->main) {
        return DECLINED;
    }

    /* Is DNT set? */
    const char *dnt_is_set = apr_table_get( r->headers_in, "DNT" );
    _DEBUG && fprintf( stderr, "DNT: %s\n", dnt_is_set );

    /* Do we already have a cookie? */
    char *cur_cookie_value = NULL;
    if( (cookie_header = apr_table_get(r->headers_in, "Cookie")) ){

        // this will match the FIRST occurance of the cookiename, not
        // subsequent ones.
        if( !ap_regexec(dcfg->regexp, cookie_header, NUM_SUBS, regm, 0) ) {
            /* Our regexp,
             * ^cookie_name=([^;]+)|;[ \t]+cookie_name=([^;]+)
             * only allows for $1 or $2 to be available. ($0 is always
             * filled with the entire matched expression, not just
             * the part in parentheses.) So just check for either one
             * and assign to cookieval if present. */
            if( regm[1].rm_so != -1 ) {
                cur_cookie_value = ap_pregsub(r->pool, "$1", cookie_header,
                                       NUM_SUBS, regm);
            }
            if( regm[2].rm_so != -1 ) {
                cur_cookie_value = ap_pregsub(r->pool, "$2", cookie_header,
                                       NUM_SUBS, regm);
            }
        }
    }

    _DEBUG && fprintf( stderr, "Current Cookie: %s\n", cur_cookie_value );

    /* XFF support inspired by this patch:
       http://www.mail-archive.com/[email protected]/msg17378.html

       And this implementation for scanning for remote ip:
       http://apache.wirebrain.de/lxr/source/modules/metadata/mod_remoteip.c?v=2.3-trunk#267
    */

    // Get the IP address of the originating request
    const char *rname = NULL;   // Originating IP address
    char *xff         = NULL;   // X-Forwarded-For, or equivalent header type

    // Should we look at a header?
    if( xff = apr_table_get(r->headers_in, dcfg->cookie_ip_header) ) {

        // There might be multiple addresses in the header
        // Check if there's a comma in there somewhere

        // no comma, this is the address we can use
        if( (rname = strrchr(xff, ',')) == NULL ) {
            rname = xff;

        // whitespace/commas left, remove 'm
        } else {

            // move past the comma
            rname++;

            // and any whitespace we might find
            while( *rname == ' ' ) {
                rname++;
            }
        }

    // otherwise, get it from the remote host
    } else {
        rname = ap_get_remote_host( r->connection, r->per_dir_config,
                                    REMOTE_NAME, NULL );
    }

    _DEBUG && fprintf( stderr, "Remote Address: %s\n", rname );

    /* Determine the value of the cookie we're going to set: */
    /* Make sure we have enough room here... */
    char new_cookie_value[ _MAX_COOKIE_LENGTH ];

    // dnt is set, and we care about that
    if( dnt_is_set && dcfg->comply_with_dnt ) {

        // you don't want us to set a cookie, alright then our work is done.
        if( !dcfg->set_dnt_cookie ) {
            return DECLINED;
        }

        char *dnt_value = dcfg->dnt_value;

        // you already ahve a cookie, but it might be whitelisted
        if( cur_cookie_value ) {

            // you might have whitelisted this value; let's check
            // Following tutorial code here again:
            // http://dev.ariel-networks.com/apr/apr-tutorial/html/apr-tutorial-19.html
            int i;
            for( i = 0; i < dcfg->dnt_exempt->nelts; i++ ) {
                _DEBUG && fprintf( stderr, "e: %d\n", i );

                char *exempt = ((char **)dcfg->dnt_exempt->elts)[i];

                //it's indeed whiteliested, we should use this value instead
                if( strcasecmp( cur_cookie_value, exempt ) == 0 ) {
                    _DEBUG && fprintf( stderr,
                        "Cookie %s is DNT exempt\n", cur_cookie_value );

                    dnt_value = exempt;
                }
            }
        }

        // dnt_value is a pointer, hence the sprintf
        sprintf( new_cookie_value, "%s", dnt_value );

    // No DNT header, so we need a cookie value to set
    } else {

        // there already is a cookie set
        if( cur_cookie_value ) {

            // but it's set to the DNT cookie
            if( strcasecmp( cur_cookie_value, dcfg->dnt_value ) == 0 ) {

                // if we have some sort of library that's generating the
                // UID, call that with the cookie we would be setting
                if( _EXTERNAL_UID_FUNCTION ) {
                    char ts[ _MAX_COOKIE_LENGTH ];
                    sprintf( ts, "%" APR_TIME_T_FMT, apr_time_now() );
                    gen_uid( new_cookie_value, ts, rname );

                // otherwise, just set it
                } else {
                    sprintf( new_cookie_value,
                             "%s.%" APR_TIME_T_FMT, rname, apr_time_now() );
                }

            // it's set to something reasonable - note we're still setting
            // a new cookie, even when there's no expires requested, because
            // we don't know if there's an expires on the /current/ cookie.
            // this could be added, but this seems to work for now.
            } else {
                // XXX we use a apr_pstrndup instead, so we can't overflow
                // the buffer if we get sent garbage
                // The return value is a
                sprintf( new_cookie_value, "%s",
                    apr_pstrndup( r->pool, cur_cookie_value, _MAX_COOKIE_LENGTH ) );

            }

        // it's either carbage, or not set; either way,
        // we need to generate a new one
        } else {
            // if we have some sort of library that's generating the
            // UID, call that with the cookie we would be setting
            if( _EXTERNAL_UID_FUNCTION ) {
                char ts[ _MAX_COOKIE_LENGTH ];
                sprintf( ts, "%" APR_TIME_T_FMT, apr_time_now() );
                gen_uid( new_cookie_value, ts, rname );

            // otherwise, just set it
            } else {
                sprintf( new_cookie_value,
                         "%s.%" APR_TIME_T_FMT, rname, apr_time_now() );
            }
        }
    }

    _DEBUG && fprintf( stderr, "New cookie: %s\n", new_cookie_value );

    /* Set the cookie in a note, for logging */
    apr_table_setn(r->notes, dcfg->note_name, new_cookie_value);

    make_cookie(r,  new_cookie_value,
                    cur_cookie_value,
                    (dnt_is_set && dcfg->comply_with_dnt)   // should we use dnt expires?
                );

    // We need to flush the stream for messages to appear right away.
    // Performing an fflush() in a production system is not good for
    // performance - don't do this for real.
    _DEBUG && fflush(stderr);

    return OK;                  /* We set our cookie */
}
Exemplo n.º 27
0
static int ip_in_url_test (request_rec *r, apr_sockaddr_t *ip_to_be_test,
                           REMOTE_INFO *p_remote_info, apr_time_t expire_time)
{
    apr_status_t rv;
    char errmsg_buf[120];

#ifdef DEBUG
    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
                  "cur_time: %lld | last_contact_time:"
                  " %lld | last_update_time: %s | expire_time: %lld",
                  apr_time_now (), p_remote_info->last_contact_time,
                  p_remote_info->last_update_time, expire_time);
#endif

#if APR_HAS_THREADS
    if (apr_time_now () - p_remote_info->last_contact_time
        >= expire_time) { /* the ip-list from url is expired */
        rv = apr_thread_rwlock_wrlock (p_remote_info->rwlock);
        if (rv != APR_SUCCESS) {
            p_remote_info->last_contact_time = apr_time_now ();
            apr_strerror (rv, errmsg_buf, sizeof (errmsg_buf));
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                          "fail to obtain wrlock: %s", errmsg_buf);
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                          "fail to update expired data from remote url,"
                          " the ipsubnet-list remains unchanged,"
                          " after remote_expire_time next update"
                          " will be invoked by another request");
        }
        else {
                /* rejudge whether it is necessary to update */
            if (apr_time_now () - p_remote_info->last_contact_time
                >= expire_time) {
                p_remote_info->last_contact_time = apr_time_now ();
                if (update_expired_data_from_remote_info (r, p_remote_info)
                    == -1) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                                  "fail to update expired data from remote url,"
                                  " the ipsubnet-list remains unchanged,"
                                  " after remote_expire_time next update will"
                                  " be invoked by another request");
                }
            }
            rv = apr_thread_rwlock_unlock (p_remote_info->rwlock);
            if (rv != APR_SUCCESS) {
                apr_strerror (rv, errmsg_buf, sizeof(errmsg_buf));
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                              "fail to release wrlock: %s", errmsg_buf);
            }
        }
    }

    rv = apr_thread_rwlock_rdlock (p_remote_info->rwlock);
    if (rv != APR_SUCCESS) {
        apr_strerror (rv, errmsg_buf, sizeof (errmsg_buf));
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                      "fail to obtain rdlock: %s", errmsg_buf);
    }
        /* check if the request's ip is match one of the ipsubnets
         * getting from url */
    int ret = ip_in_ipsubnet_list_test (ip_to_be_test,
                                        p_remote_info->p_ipsubnet_list);
    rv = apr_thread_rwlock_unlock (p_remote_info->rwlock);
    if (rv != APR_SUCCESS) {
        apr_strerror (rv, errmsg_buf, sizeof (errmsg_buf));
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                      "fail to release rdlock: %s", errmsg_buf);
    }
    return ret;

#else
    if (apr_time_now () - p_remote_info->last_contact_time
        >= expire_time) { /* the ip-list from url is expired */
        p_remote_info->last_contact_time = apr_time_now ();
        if (update_expired_data_from_remote_info (r, p_remote_info) == -1) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                          "fail to update expired data from remote url,"
                                  " the ipsubnet-list remains unchanged,"
                                  " after remote_expire_time next update will"
                                  " be invoked by another request");
        }
    }

        /* check if the request's ip is match one
         * of the ipsubnets getting from url */
    return ip_in_ipsubnet_list_test (ip_to_be_test,
                                     p_remote_info->p_ipsubnet_list);
    
#endif
}
Exemplo n.º 28
0
mapcache_http_response *mapcache_core_get_tile(mapcache_context *ctx, mapcache_request_get_tile *req_tile)
{
  int expires = 0;
  mapcache_http_response *response;
  int i,first = -1;
  int ntiles_with_data = 0;
  char *timestr;
  mapcache_image *base=NULL,*overlay;
  mapcache_image_format *format = NULL;

#ifdef DEBUG
  if(req_tile->ntiles ==0) {
    ctx->set_error(ctx,500,"BUG: get_tile called with 0 tiles");
    return NULL;
  }
#endif
  expires = 0;
  response = mapcache_http_response_create(ctx->pool);


  mapcache_prefetch_tiles(ctx,req_tile->tiles,req_tile->ntiles);
  if(GC_HAS_ERROR(ctx))
    return NULL;

  /* count how many tiles actually contain data */
  for(i=0; i<req_tile->ntiles; i++) {
    /* add 1 if tile->nodata == 0 */
    ntiles_with_data -= req_tile->tiles[i]->nodata - 1;
  }
  if(ntiles_with_data == 0) {
    ctx->set_error(ctx,404,
                   "no tiles containing image data could be retrieved (not in cache, and read-only tileset or no source configured)");
    return NULL;
  }
  /* this loop retrieves the tiles from the caches, and eventually decodes and merges them together
   * if multiple tiles were asked for */
  for(i=0; i<req_tile->ntiles; i++) {
    mapcache_tile *tile = req_tile->tiles[i];
    if(tile->nodata) continue;
    if(first == -1) {
      first = i;
      response->mtime = tile->mtime;
      expires = tile->expires;
      /* if we have multiple tiles to merge, decode the image data */
      if(ntiles_with_data>1) {
        if(!tile->raw_image) {
          tile->raw_image = mapcache_imageio_decode(ctx, tile->encoded_data);
          if(!tile->raw_image) return NULL;
        }
        base = tile->raw_image;
      }
    } else {
      if(response->mtime < tile->mtime)
        response->mtime = tile->mtime;
      if(tile->expires < expires) {
        expires = tile->expires;
      }
      if(!tile->raw_image) {
        tile->raw_image = mapcache_imageio_decode(ctx, tile->encoded_data);
        if(!tile->raw_image) return NULL;
      }
      overlay = tile->raw_image;
      mapcache_image_merge(ctx, base, overlay);
      if(GC_HAS_ERROR(ctx)) {
        return NULL;
      }
    }
  }
  format = NULL;

  /* if we had more than one tile, we need to encode the raw image data into a mapcache_buffer */
  if(ntiles_with_data > 1) {
    if(req_tile->format) {
      format = req_tile->format;
    } else {
      format = req_tile->tiles[first]->tileset->format;
      if(!format) {
        format = ctx->config->default_image_format; /* this one is always defined */
      }
    }
    response->data = format->write(ctx, base, format);
    if(GC_HAS_ERROR(ctx)) {
      return NULL;
    }
  } else {
    response->data = req_tile->tiles[first]->encoded_data;
    format = req_tile->tiles[first]->tileset->format;
  }

  /* compute the content-type */
  if(format && format->mime_type) {
    apr_table_set(response->headers,"Content-Type",format->mime_type);
  } else {
    mapcache_image_format_type t = mapcache_imageio_header_sniff(ctx,response->data);
    if(t == GC_PNG)
      apr_table_set(response->headers,"Content-Type","image/png");
    else if(t == GC_JPEG)
      apr_table_set(response->headers,"Content-Type","image/jpeg");
  }

  /* compute expiry headers */
  if(expires) {
    apr_time_t now = apr_time_now();
    apr_time_t additional = apr_time_from_sec(expires);
    apr_time_t texpires = now + additional;
    apr_table_set(response->headers, "Cache-Control",apr_psprintf(ctx->pool, "max-age=%d", expires));
    timestr = apr_palloc(ctx->pool, APR_RFC822_DATE_LEN);
    apr_rfc822_date(timestr, texpires);
    apr_table_setn(response->headers, "Expires", timestr);
  }

  return response;
}
Exemplo n.º 29
0
static PyObject *wsgi_process_metrics(void)
{
    PyObject *result = NULL;

    PyObject *object = NULL;

    PyObject *thread_list = NULL;
    WSGIThreadInfo **thread_info = NULL;

    int i;

#ifdef HAVE_TIMES
    struct tms tmsbuf; 
    static float tick = 0.0;
#endif

    apr_time_t current_time;
    apr_interval_time_t running_time;

    if (!wsgi_interns_initialized)
        wsgi_initialize_interned_strings();

#if 0
    if (!wsgi_daemon_pool) {
        if (!wsgi_server_config->server_metrics) {
            Py_INCREF(Py_None);

            return Py_None;
        }
    }
#if defined(MOD_WSGI_WITH_DAEMONS)
    else {
        if (!wsgi_daemon_process->group->server_metrics) {
            Py_INCREF(Py_None);

            return Py_None;
        }
    }
#endif
#endif

    result = PyDict_New();

    object = wsgi_PyInt_FromLong(getpid());
    PyDict_SetItem(result,
            WSGI_INTERNED_STRING(pid), object);
    Py_DECREF(object);

    object = wsgi_PyInt_FromLongLong(wsgi_total_requests);
    PyDict_SetItem(result,
            WSGI_INTERNED_STRING(request_count), object);
    Py_DECREF(object);

    object = PyFloat_FromDouble(wsgi_utilization_time(0));
    PyDict_SetItem(result,
            WSGI_INTERNED_STRING(request_busy_time), object);
    Py_DECREF(object);

    object = wsgi_PyInt_FromLongLong(wsgi_get_peak_memory_RSS());
    PyDict_SetItem(result,
            WSGI_INTERNED_STRING(memory_max_rss), object);
    Py_DECREF(object);

    object = wsgi_PyInt_FromLongLong(wsgi_get_current_memory_RSS());
    PyDict_SetItem(result,
            WSGI_INTERNED_STRING(memory_rss), object);
    Py_DECREF(object);

#ifdef HAVE_TIMES
    if (!tick) {
#ifdef _SC_CLK_TCK
        tick = sysconf(_SC_CLK_TCK);
#else
        tick = HZ;
#endif
    }

    times(&tmsbuf);

    object = PyFloat_FromDouble(tmsbuf.tms_utime / tick);
    PyDict_SetItem(result,
            WSGI_INTERNED_STRING(cpu_user_time), object);
    Py_DECREF(object);

    object = PyFloat_FromDouble(tmsbuf.tms_stime / tick);
    PyDict_SetItem(result,
            WSGI_INTERNED_STRING(cpu_system_time), object);
    Py_DECREF(object);
#endif

    object = PyFloat_FromDouble(apr_time_sec((double)wsgi_restart_time));
    PyDict_SetItem(result,
            WSGI_INTERNED_STRING(restart_time), object);
    Py_DECREF(object);

    current_time = apr_time_now();

    object = PyFloat_FromDouble(apr_time_sec((double)current_time));
    PyDict_SetItem(result,
            WSGI_INTERNED_STRING(current_time), object);
    Py_DECREF(object);

    running_time = (apr_uint32_t)apr_time_sec((double)
            current_time - wsgi_restart_time);

    object = wsgi_PyInt_FromLongLong(running_time);
    PyDict_SetItem(result,
            WSGI_INTERNED_STRING(running_time), object);
    Py_DECREF(object);

    object = wsgi_PyInt_FromLong(wsgi_request_threads);
    PyDict_SetItem(result,
            WSGI_INTERNED_STRING(request_threads), object);
    Py_DECREF(object);

    object = wsgi_PyInt_FromLong(wsgi_active_requests);
    PyDict_SetItem(result,
            WSGI_INTERNED_STRING(active_requests), object);
    Py_DECREF(object);

    thread_list = PyList_New(0);

    PyDict_SetItem(result, WSGI_INTERNED_STRING(threads), thread_list);

    thread_info = (WSGIThreadInfo **)wsgi_thread_details->elts;

    for (i=0; i<wsgi_thread_details->nelts; i++) {
        PyObject *entry = NULL;

        if (thread_info[i]->request_thread) {
            entry = PyDict_New();

            object = wsgi_PyInt_FromLong(thread_info[i]->thread_id);
            PyDict_SetItem(entry, WSGI_INTERNED_STRING(thread_id), object);
            Py_DECREF(object);

            object = wsgi_PyInt_FromLongLong(thread_info[i]->request_count);
            PyDict_SetItem(entry, WSGI_INTERNED_STRING(request_count), object);
            Py_DECREF(object);

            PyList_Append(thread_list, entry);

            Py_DECREF(entry);
        }
    }

    Py_DECREF(thread_list);

    return result;
}
Exemplo n.º 30
0
static int reflector_handler(request_rec * r)
{
    apr_bucket_brigade *bbin, *bbout;
    reflector_cfg *conf;
    apr_status_t status;

    if (strcmp(r->handler, "reflector")) {
        return DECLINED;
    }

    conf = (reflector_cfg *) ap_get_module_config(r->per_dir_config,
                                                  &reflector_module);

    ap_allow_methods(r, 1, "POST", "OPTIONS", NULL);

    if (r->method_number == M_OPTIONS) {
        return ap_send_http_options(r);
    }

    else if (r->method_number == M_POST) {
        const char *content_length, *content_type;
        int seen_eos;

        /*
         * Sometimes we'll get in a state where the input handling has
         * detected an error where we want to drop the connection, so if
         * that's the case, don't read the data as that is what we're trying
         * to avoid.
         *
         * This function is also a no-op on a subrequest.
         */
        if (r->main || r->connection->keepalive == AP_CONN_CLOSE ||
            ap_status_drops_connection(r->status)) {
            return OK;
        }

        /* copy headers from in to out if configured */
        apr_table_do(header_do, r, conf->headers, NULL);

        /* last modified defaults to now, unless otherwise set on the way in */
        if (!apr_table_get(r->headers_out, "Last-Modified")) {
            ap_update_mtime(r, apr_time_now());
            ap_set_last_modified(r);
        }
        ap_set_accept_ranges(r);

        /* reflect the content length, if present */
        if ((content_length = apr_table_get(r->headers_in, "Content-Length"))) {
            apr_off_t offset;

            apr_strtoff(&offset, content_length, NULL, 10);
            ap_set_content_length(r, offset);

        }

        /* reflect the content type, if present */
        if ((content_type = apr_table_get(r->headers_in, "Content-Type"))) {

            ap_set_content_type(r, content_type);

        }

        bbin = apr_brigade_create(r->pool, r->connection->bucket_alloc);
        bbout = apr_brigade_create(r->pool, r->connection->bucket_alloc);

        seen_eos = 0;
        do {
            apr_bucket *bucket;

            status = ap_get_brigade(r->input_filters, bbin, AP_MODE_READBYTES,
                                    APR_BLOCK_READ, HUGE_STRING_LEN);

            if (status != APR_SUCCESS) {
                if (status == AP_FILTER_ERROR) {
                    apr_brigade_destroy(bbin);
                    return status;
                }
                else {
                    apr_brigade_destroy(bbin);
                    return HTTP_BAD_REQUEST;
                }
            }

            for (bucket = APR_BRIGADE_FIRST(bbin);
                 bucket != APR_BRIGADE_SENTINEL(bbin);
                 bucket = APR_BUCKET_NEXT(bucket)) {
                const char *data;
                apr_size_t len;

                if (APR_BUCKET_IS_EOS(bucket)) {
                    seen_eos = 1;
                    break;
                }

                /* These are metadata buckets. */
                if (bucket->length == 0) {
                    continue;
                }

                /*
                 * We MUST read because in case we have an unknown-length
                 * bucket or one that morphs, we want to exhaust it.
                 */
                status = apr_bucket_read(bucket, &data, &len, APR_BLOCK_READ);
                if (status != APR_SUCCESS) {
                    apr_brigade_destroy(bbin);
                    return HTTP_BAD_REQUEST;
                }

                apr_brigade_write(bbout, NULL, NULL, data, len);

                status = ap_pass_brigade(r->output_filters, bbout);
                if (status != APR_SUCCESS) {
                    /* no way to know what type of error occurred */
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, status, r, APLOGNO(01410)
                             "reflector_handler: ap_pass_brigade returned %i",
                                  status);
                    return HTTP_INTERNAL_SERVER_ERROR;
                }

            }

            apr_brigade_cleanup(bbin);

        } while (!seen_eos);

        return OK;

    }

    else {
        return HTTP_METHOD_NOT_ALLOWED;
    }

}