Exemple #1
0
ret_t
cherokee_validator_file_get_full_path (cherokee_validator_file_t  *validator,
				       cherokee_connection_t      *conn,
				       cherokee_buffer_t         **ret_buf,
				       cherokee_buffer_t          *tmp)
{
	cherokee_validator_file_props_t *props = VAL_VFILE_PROP(validator);

	switch (props->password_path_type) {
	case val_path_full:
		*ret_buf = &props->password_file;
		return ret_ok;

	case val_path_local_dir:
		cherokee_buffer_clean (tmp);
		cherokee_buffer_add_buffer (tmp, &conn->local_directory);
		cherokee_buffer_add_char   (tmp, '/');
		cherokee_buffer_add_buffer (tmp, &props->password_file);

		*ret_buf = tmp;
		return ret_ok;

	default:
		SHOULDNT_HAPPEN;
	}

	return ret_error;
}
Exemple #2
0
static void
render_human_error (cherokee_error_type_t   type,
		    const char             *filename,
		    int                     line,
		    int                     error_num,
		    const cherokee_error_t *error,
		    cherokee_buffer_t      *output,
		    va_list                 ap)
{
	UNUSED (error_num);

	/* Time */
	cherokee_buffer_add_char (output, '[');
	cherokee_buf_add_bogonow (output, false);
	cherokee_buffer_add_str  (output, "] ");

	/* Error type */
	switch (type) {
	case cherokee_err_warning:
		cherokee_buffer_add_str (output, "(warning)");
		break;
	case cherokee_err_error:
		cherokee_buffer_add_str (output, "(error)");
		break;
	case cherokee_err_critical:
		cherokee_buffer_add_str (output, "(critical)");
		break;
	default:
		SHOULDNT_HAPPEN;
	}

	/* Source */
	cherokee_buffer_add_va (output, " %s:%d - ", filename, line);

	/* Error */
	cherokee_buffer_add_va_list (output, error->title, ap);
	cherokee_buffer_add_char    (output, '\n');

	/* Backtrace */
#ifdef BACKTRACES_ENABLED
	cherokee_buf_add_backtrace (output, 2, "\n", "  ");
#endif
}
Exemple #3
0
static ret_t
generate_password (cherokee_buffer_t *buf)
{
	cuint_t i;
	cuint_t n;

	for (i=0; i<PASSWORD_LEN; i++) {
		n = cherokee_random()%(sizeof(ALPHA_NUM)-1);
		cherokee_buffer_add_char (buf, ALPHA_NUM[n]);
	}

	return ret_ok;
}
static ret_t
while_print_name (cherokee_buffer_t *key, void *value, void *param)
{
	entry_t           *entry  = value;
	cherokee_buffer_t *buffer = param;

	if (entry->built_in) {
		cherokee_buffer_add_buffer (buffer, key);
		cherokee_buffer_add_char   (buffer, ' ');
	}

	return ret_ok;
}
Exemple #5
0
static ret_t
write_logger (cherokee_buffer_t        *buf,
              cherokee_logger_writer_t *error_writer)
{
    int val;

    /* No writer
     */
    if (error_writer == NULL) {
        goto nothing;
    }

    switch (error_writer->type) {
    case cherokee_logger_writer_stderr:
        val = 6;
        cherokee_buffer_add      (buf, (char *)&val, sizeof(int));
        cherokee_buffer_add_str  (buf, "stderr");
        cherokee_buffer_add_char (buf, '\0');
        break;
    case cherokee_logger_writer_file:
        val = 5 + error_writer->filename.len;
        cherokee_buffer_add        (buf, (char *)&val, sizeof(int));
        cherokee_buffer_add_str    (buf, "file,");
        cherokee_buffer_add_buffer (buf, &error_writer->filename);
        cherokee_buffer_add_char   (buf, '\0');
        break;
    default:
        goto nothing;
    }

    return ret_ok;

nothing:
    val = 0;
    cherokee_buffer_add (buf, (char *)&val, sizeof(int));
    return ret_ok;
}
static ret_t
generate_admin_password (cherokee_buffer_t *buf)
{
	cuint_t i;
	cuint_t n;

	srand(getpid()*time(NULL));

	for (i=0; i<PASSWORD_LEN; i++) {
		n = rand()%(sizeof(ALPHA_NUM)-1);
		cherokee_buffer_add_char (buf, ALPHA_NUM[n]);
	}

	return ret_ok;
}
Exemple #7
0
ret_t
cherokee_url_build_string (cherokee_url_t *url, cherokee_buffer_t *buf)
{
	cherokee_buffer_add_buffer (buf, &url->host);

	if (((url->protocol == http)  && (url->port != 80)) ||
	    ((url->protocol == https) && (url->port != 443))) {
		cherokee_buffer_add_char (buf, ':');
		cherokee_buffer_add_ulong10 (buf, (culong_t) url->port);
	}

	cherokee_buffer_add_buffer (buf, &url->request);

	return ret_ok;
}
Exemple #8
0
ret_t
cherokee_url_build_string (cherokee_url_t *url, cherokee_buffer_t *buf)
{
	cherokee_buffer_add_buffer (buf, &url->host);

	if (! http_port_is_standard (url->port, (url->protocol == https)))
	{
		cherokee_buffer_add_char (buf, ':');
		cherokee_buffer_add_ulong10 (buf, (culong_t) url->port);
	}

	cherokee_buffer_add_buffer (buf, &url->request);

	return ret_ok;
}
ret_t
cherokee_handler_proxy_hosts_get (cherokee_handler_proxy_hosts_t  *hosts,
				  cherokee_source_t               *src,
				  cherokee_handler_proxy_poll_t  **poll,
				  cuint_t                          reuse_max)
{
	ret_t ret;

	CHEROKEE_MUTEX_LOCK (&hosts->hosts_mutex);

	/* Build the index name */
	cherokee_buffer_clean       (&hosts->tmp);
	cherokee_buffer_add_buffer  (&hosts->tmp, &src->host);
	cherokee_buffer_add_char    (&hosts->tmp, ':');
	cherokee_buffer_add_ulong10 (&hosts->tmp, src->port);

	/* Check the hosts tree */
	ret = cherokee_avl_get (&hosts->hosts, &hosts->tmp, (void **)poll);
	switch (ret) {
	case ret_ok:
		break;
	case ret_not_found: {
		cherokee_handler_proxy_poll_t *n;

		ret = cherokee_handler_proxy_poll_new (&n, reuse_max);
		if (ret != ret_ok)
			return ret;

		cherokee_avl_add (&hosts->hosts, &hosts->tmp, n);
		*poll = n;
		break;
	}
	default:
		goto error;
	}

	/* Got it */
	CHEROKEE_MUTEX_UNLOCK (&hosts->hosts_mutex);
	return ret_ok;

error:
	CHEROKEE_MUTEX_LOCK (&hosts->hosts_mutex);
	return ret_error;
}
Exemple #10
0
ret_t
cherokee_spawner_spawn (cherokee_buffer_t         *binary,
                        cherokee_buffer_t         *user,
                        uid_t                      uid,
                        gid_t                      gid,
                        int                        env_inherited,
                        char                     **envp,
                        cherokee_logger_writer_t  *error_writer,
                        pid_t                     *pid_ret)
{
#ifdef HAVE_SYSV_SEMAPHORES
    char             **n;
    int               *pid_shm;
    int                pid_prev;
    int                k;
    int                phase;
    int                envs     = 0;
    cherokee_buffer_t  tmp      = CHEROKEE_BUF_INIT;

#define ALIGN4(buf)						\
	while (buf.len & 0x3) {					\
		cherokee_buffer_add_char (&buf, '\0');		\
	}


    /* Check it's initialized
     */
    if ((! _active) ||
            (cherokee_spawn_shared.mem == NULL))
    {
        TRACE (ENTRIES, "Spawner is not active. Returning: %s\n", binary->buf);
        return ret_deny;
    }

    /* Lock the monitor mutex
     */
    k = CHEROKEE_MUTEX_TRY_LOCK (&spawning_mutex);
    if (k) {
        return ret_eagain;
    }

    /* Build the string
     * The first character of each block is a mark.
     */
    cherokee_buffer_ensure_size (&tmp, SPAWN_SHARED_LEN);

    /* 1.- Executable */
    phase = 0xF0;
    cherokee_buffer_add        (&tmp, (char *)&phase, sizeof(int));
    cherokee_buffer_add        (&tmp, (char *)&binary->len,   sizeof(int));
    cherokee_buffer_add_buffer (&tmp, binary);
    cherokee_buffer_add_char   (&tmp, '\0');
    ALIGN4 (tmp);

    /* 2.- UID & GID */
    phase = 0xF1;
    cherokee_buffer_add        (&tmp, (char *)&phase, sizeof(int));
    cherokee_buffer_add        (&tmp, (char *)&user->len, sizeof(int));
    cherokee_buffer_add_buffer (&tmp, user);
    cherokee_buffer_add_char   (&tmp, '\0');
    ALIGN4(tmp);

    cherokee_buffer_add (&tmp, (char *)&uid, sizeof(uid_t));
    cherokee_buffer_add (&tmp, (char *)&gid, sizeof(gid_t));

    /* 3.- Environment */
    phase = 0xF2;
    cherokee_buffer_add (&tmp, (char *)&phase, sizeof(int));

    for (n=envp; *n; n++) {
        envs ++;
    }

    cherokee_buffer_add (&tmp, (char *)&env_inherited, sizeof(int));
    cherokee_buffer_add (&tmp, (char *)&envs, sizeof(int));

    for (n=envp; *n; n++) {
        int len = strlen(*n);
        cherokee_buffer_add      (&tmp, (char *)&len, sizeof(int));
        cherokee_buffer_add      (&tmp, *n, len);
        cherokee_buffer_add_char (&tmp, '\0');
        ALIGN4(tmp);
    }

    /* 4.- Error log */
    phase = 0xF3;
    cherokee_buffer_add (&tmp, (char *)&phase, sizeof(int));

    write_logger (&tmp, error_writer);
    ALIGN4 (tmp);

    /* 5.- PID (will be rewritten by the other side) */
    phase = 0xF4;
    cherokee_buffer_add (&tmp, (char *)&phase, sizeof(int));

    pid_shm = (int *) (((char *)cherokee_spawn_shared.mem) + tmp.len);
    k        = *pid_ret;
    pid_prev = *pid_ret;
    cherokee_buffer_add (&tmp, (char *)&k, sizeof(int));

    /* Copy it to the shared memory
     */
    if (unlikely (tmp.len > SPAWN_SHARED_LEN)) {
        goto error;
    }

    memcpy (cherokee_spawn_shared.mem, tmp.buf, tmp.len);
    cherokee_buffer_mrproper (&tmp);

    /* Wake up the spawning thread
     */
    sem_unlock (cherokee_spawn_sem, SEM_LAUNCH_START);

    /* Wait for the PID
     */
    sem_adquire (cherokee_spawn_sem, SEM_LAUNCH_READY);

    if (*pid_shm == -1) {
        TRACE(ENTRIES, "Could not get the PID of: '%s'\n", binary->buf);
        goto error;
    }

    if (*pid_shm == pid_prev) {
        TRACE(ENTRIES, "Could not the new PID, previously it was %d\n", pid_prev);
        goto error;
    }

    TRACE(ENTRIES, "Successfully launched PID=%d\n", *pid_shm);
    *pid_ret = *pid_shm;

    CHEROKEE_MUTEX_UNLOCK (&spawning_mutex);
    return ret_ok;

error:
    CHEROKEE_MUTEX_UNLOCK (&spawning_mutex);
    return ret_error;
#else
    return ret_not_found;

#endif /* HAVE_SYSV_SEMAPHORES */
}
Exemple #11
0
static void
render_python_error (cherokee_error_type_t   type,
		     const char             *filename,
		     int                     line,
		     int                     error_num,
		     const cherokee_error_t *error,
		     cherokee_buffer_t      *output,
		     va_list                 ap)
{
	cherokee_buffer_t tmp = CHEROKEE_BUF_INIT;

	/* Dict: open */
	cherokee_buffer_add_char (output, '{');

	/* Error type */
	cherokee_buffer_add_str (output, "'type': \"");

	switch (type) {
	case cherokee_err_warning:
		cherokee_buffer_add_str (output, "warning");
		break;
	case cherokee_err_error:
		cherokee_buffer_add_str (output, "error");
		break;
	case cherokee_err_critical:
		cherokee_buffer_add_str (output, "critical");
		break;
	default:
		SHOULDNT_HAPPEN;
	}
	cherokee_buffer_add_str (output, "\", ");

	/* Time */
	cherokee_buffer_add_str  (output, "'time': \"");
	cherokee_buf_add_bogonow (output, false);
	cherokee_buffer_add_str  (output, "\", ");

	/* Render the title */
	cherokee_buffer_add_str     (output, "'title': \"");
	cherokee_buffer_add_va_list (output, error->title, ap);
	cherokee_buffer_add_str     (output, "\", ");
	skip_args (ap, error->title);

	/* File and line*/
	cherokee_buffer_add_str (output, "'code': \"");
	cherokee_buffer_add_va  (output, "%s:%d", filename, line);
	cherokee_buffer_add_str (output, "\", ");

	/* Error number */
	cherokee_buffer_add_str (output, "'error': \"");
	cherokee_buffer_add_va  (output, "%d", error_num);
	cherokee_buffer_add_str (output, "\", ");

	/* Description */
	if (error->description) {
		cherokee_buffer_add_str     (output, "'description': \"");
		cherokee_buffer_clean       (&tmp);
		cherokee_buffer_add_va_list (&tmp, error->description, ap);
		cherokee_buffer_add_escape_html (output, &tmp);
		cherokee_buffer_add_str     (output, "\", ");
		skip_args (ap, error->description);
	}

	/* Admin URL */
	if (error->admin_url) {
		cherokee_buffer_add_str     (output, "'admin_url': \"");
		cherokee_buffer_add_va_list (output, error->admin_url, ap);
		cherokee_buffer_add_str     (output, "\", ");

		/* ARGS: Skip 'admin_url' */
		skip_args (ap, error->admin_url);
	}

	/* Debug information */
	if (error->debug) {
		cherokee_buffer_add_str     (output, "'debug': \"");
		cherokee_buffer_add_va_list (output, error->debug, ap);
		cherokee_buffer_add_str     (output, "\", ");

		/* ARGS: Skip 'debug' */
		skip_args (ap, error->debug);
	}

	/* Version */
	cherokee_buffer_add_str (output, "'version': \"");
	cherokee_buffer_add_str (output, PACKAGE_VERSION);
	cherokee_buffer_add_str (output, "\", ");

	cherokee_buffer_add_str (output, "'compilation_date': \"");
	cherokee_buffer_add_str (output, __DATE__ " " __TIME__);
	cherokee_buffer_add_str (output, "\", ");

	cherokee_buffer_add_str (output, "'configure_args': \"");
	cherokee_buffer_clean   (&tmp);
	cherokee_buffer_add_str (&tmp, CHEROKEE_CONFIG_ARGS);
	cherokee_buffer_add_escape_html (output, &tmp);
	cherokee_buffer_add_buffer (output, &tmp);
	cherokee_buffer_add_str (output, "\", ");

	/* Backtrace */
	cherokee_buffer_add_str (output, "'backtrace': \"");
#ifdef BACKTRACES_ENABLED
	cherokee_buffer_clean (&tmp);
	cherokee_buf_add_backtrace (&tmp, 2, "\\n", "");
	cherokee_buffer_add_escape_html (output, &tmp);
#endif
	cherokee_buffer_add_str (output, "\", ");

	/* Let's finish here.. */
	if (strcmp (output->buf + output->len - 2, ", ") == 0) {
		cherokee_buffer_drop_ending (output, 2);
	}
	cherokee_buffer_add_str (output, "}\n");

	/* Clean up */
	cherokee_buffer_mrproper (&tmp);
}
Exemple #12
0
static ret_t
entry_fill_up (cherokee_resolv_cache_entry_t *entry,
	       cherokee_buffer_t             *domain)
{
	ret_t            ret;
	char             tmp[46];       // Max IPv6 length is 45
	struct addrinfo *addr;
	time_t           eagain_at = 0;

	while (true) {
		ret = cherokee_gethostbyname (domain, &entry->addr);
		if (ret == ret_ok) {
			break;

		} else if (ret == ret_eagain) {
			if (eagain_at == 0) {
				eagain_at = cherokee_bogonow_now;

			} else if (cherokee_bogonow_now > eagain_at + 3) {
			      	LOG_WARNING (CHEROKEE_ERROR_RESOLVE_TIMEOUT, domain->buf);
				return ret_error;
			}

			CHEROKEE_THREAD_YIELD;
			continue;

		} else {
			return ret_error;
		}
	}

	if (unlikely (entry->addr == NULL)) {
		return ret_error;
	}

	/* Render the text representation
	 */
	ret = cherokee_ntop (entry->addr->ai_family, entry->addr->ai_addr, tmp, sizeof(tmp));
	if (ret != ret_ok) {
		return ret_error;
	}

	cherokee_buffer_add (&entry->ip_str, tmp, strlen(tmp));

	/* Render the text representation (all the IPs)
	 */
	cherokee_buffer_add_buffer (&entry->ip_str_all, &entry->ip_str);

	addr = entry->addr;
	while (addr != NULL) {
		ret = cherokee_ntop (entry->addr->ai_family, addr->ai_addr, tmp, sizeof(tmp));
		if (ret != ret_ok) {
			return ret_error;
		}

		cherokee_buffer_add_char (&entry->ip_str_all, ',');
		cherokee_buffer_add      (&entry->ip_str_all, tmp, strlen(tmp));

		addr = addr->ai_next;
	}

	return ret_ok;
}
Exemple #13
0
static ret_t
build_log_string (cherokee_logger_ncsa_t *logger,
		  cherokee_connection_t  *cnt,
		  cherokee_buffer_t      *buf)
{
	ret_t              ret;
	const char        *method;
	const char        *username;
	const char        *version;
	cuint_t            method_len                   = 0;
	size_t             username_len                 = 0;
	cuint_t            version_len                  = 0;
	cherokee_buffer_t *referer                      = &logger->referer;
	cherokee_buffer_t *useragent                    = &logger->useragent;
	char               ipaddr[CHE_INET_ADDRSTRLEN];

	/* Look for the user
	 */
	if (cnt->validator && !cherokee_buffer_is_empty (&cnt->validator->user)) {
		username_len = cnt->validator->user.len;
		username = cnt->validator->user.buf;
	} else {
		username_len = 1;
		username = "******";
	}

	/* Get the method and version strings
	 */
	ret = cherokee_http_method_to_string (cnt->header.method, &method, &method_len);
	if (unlikely (ret < ret_ok)) {
		method     = "";
		method_len = 0;
	}

	ret = cherokee_http_version_to_string (cnt->header.version, &version, &version_len);
	if (unlikely (ret < ret_ok)) {
		version     = "";
		version_len = 0;
	}

	/* Build the log string
	 *
	 * "%s - %s [%02d/%s/%d:%02d:%02d:%02d %c%02d%02d] \"%s %s %s\" %d "
	 * FMT_OFFSET
	 */
	if (cherokee_buffer_is_empty (&cnt->logger_real_ip)) {
		memset (ipaddr, 0, sizeof(ipaddr));
		cherokee_socket_ntop (&cnt->socket, ipaddr, sizeof(ipaddr)-1);
		cherokee_buffer_add (buf, ipaddr, strlen(ipaddr));
	} else {
		cherokee_buffer_add_buffer (buf, &cnt->logger_real_ip);
	}

	cherokee_buffer_add_str (buf, " - ");
	cherokee_buffer_add     (buf, username, username_len);

	/* " [date time] "
	 */
	cherokee_buffer_add_buffer (buf, &now);
	cherokee_buffer_add        (buf, method, method_len);
	cherokee_buffer_add_char   (buf, ' ');

	if (! cherokee_buffer_is_empty (&cnt->request_original)) {
		cherokee_buffer_add_buffer (buf, &cnt->request_original);
		if (! cherokee_buffer_is_empty (&cnt->query_string_original)) {
			cherokee_buffer_add_char   (buf, '?');
			cherokee_buffer_add_buffer (buf, &cnt->query_string_original);
		}
	} else {
		cherokee_buffer_add_buffer (buf, &cnt->request);
		if (! cherokee_buffer_is_empty (&cnt->query_string)) {
			cherokee_buffer_add_char   (buf, '?');
			cherokee_buffer_add_buffer (buf, &cnt->query_string);
		}
	}

	cherokee_buffer_add_char   (buf, ' ');
	cherokee_buffer_add        (buf, version, version_len);
	cherokee_buffer_add_str    (buf, "\" ");

	if (unlikely (cnt->error_internal_code != http_unset)) {
		cherokee_buffer_add_long10 (buf, cnt->error_internal_code);
	} else {
		cherokee_buffer_add_long10 (buf, cnt->error_code);
	}

	cherokee_buffer_add_char (buf, ' ');
	cherokee_buffer_add_ullong10 (buf, cnt->tx);

	/* Look for the "combined" information
	 */
	if (!logger->combined) {
		cherokee_buffer_add_char (buf, '\n');
		return ret_ok;
	}

	/* "combined" information
	 */
	cherokee_buffer_clean (referer);
	cherokee_buffer_clean (useragent);

	cherokee_header_copy_known (&cnt->header, header_referer, referer);
	cherokee_header_copy_known (&cnt->header, header_user_agent, useragent);
	cherokee_buffer_ensure_addlen (buf, 8 + referer->len + referer->len);

	if (referer->len > 0) {
		cherokee_buffer_add_str    (buf, " \"");
		cherokee_buffer_add_buffer (buf, referer);
		cherokee_buffer_add_str    (buf, "\" \"");
	} else {
		cherokee_buffer_add_str (buf, " \"-\" \"");
	}

	if (useragent->len > 0) {
		cherokee_buffer_add_buffer (buf, useragent);
	}

	cherokee_buffer_add_str (buf, "\"\n");
	return ret_ok;
}
Exemple #14
0
ret_t
cherokee_request_header_build_string (cherokee_request_header_t *request, cherokee_buffer_t *buf, cherokee_buffer_t *tmp1, cherokee_buffer_t *tmp2)
{
	ret_t           ret;
	const char     *ptr;
	cuint_t         len;
	cherokee_url_t *url = REQUEST_URL(request);

	/* 200 bytes should be enough for a small header
	 */
	cherokee_buffer_ensure_size (buf, 200);

	/* Add main request line:
	 * GET /dir/object HTTP/1.1
	 */
	ret = cherokee_http_method_to_string (request->method, &ptr, &len);
	if (ret != ret_ok) return ret;

	ret = cherokee_buffer_add (buf, ptr, len);
	if (ret != ret_ok) return ret;

	cherokee_buffer_add_str (buf, " ");

	/* Check if the requests goes through a proxy
	 */
	if (request->proxy) {
		cherokee_buffer_add_str (buf, "http://");
		cherokee_buffer_add_buffer (buf, URL_HOST(url));
	}

	cherokee_buffer_add_buffer (buf, URL_REQUEST(url));

	switch (REQUEST_VERSION(request)) {
	case http_version_11:
		cherokee_buffer_add_str (buf, " HTTP/1.1" CRLF);
		break;
	case http_version_10:
		cherokee_buffer_add_str (buf, " HTTP/1.0" CRLF);
		break;
	default:
		SHOULDNT_HAPPEN;
		return ret_error;
	}

	/* Add "Host:" header - in HTTP/1.1
	 */
	if (REQUEST_VERSION(request) == http_version_11) {
		cherokee_buffer_add_str    (buf, "Host: ");
		cherokee_buffer_add_buffer (buf, URL_HOST(url));
		cherokee_buffer_add_str    (buf, CRLF);
	}

	/* Post information
	 */
	if (request->post_len != 0) {
		/* "Content-Length: " FMT_OFFSET CRLF, request->post_len;
		 */
		cherokee_buffer_add_str      (buf, "Content-Length: ");
		cherokee_buffer_add_ullong10 (buf, (cullong_t) request->post_len);
		cherokee_buffer_add_str      (buf, CRLF);
	}

	/* Add "Connection:" header
	 */
	if (REQUEST_KEEPALIVE(request)) {
		cherokee_buffer_add_str (buf, "Connection: Keep-Alive"CRLF);
	} else {
		cherokee_buffer_add_str (buf, "Connection: close"CRLF);
	}

	/* Authentication
	 */
	if (! cherokee_buffer_is_empty (&request->user) ||
	    ! cherokee_buffer_is_empty (&request->password)) {
		cherokee_buffer_clean (tmp1);
		cherokee_buffer_clean (tmp2);

		cherokee_buffer_add_buffer (tmp1, &request->user);
		cherokee_buffer_add_char   (tmp1, ':');
		cherokee_buffer_add_buffer (tmp1, &request->password);

		cherokee_buffer_encode_base64 (tmp1, tmp2);

		cherokee_buffer_add_str    (buf, "Authorization: Basic ");
		cherokee_buffer_add_buffer (buf, tmp2);
		cherokee_buffer_add_str    (buf, CRLF);
	}

	/* Extra headers
	 */
	if (! cherokee_buffer_is_empty (&request->extra_headers)) {
		cherokee_buffer_add_buffer (buf, &request->extra_headers);
	}

	/* Finish the header
	 */
	cherokee_buffer_add_str (buf, CRLF);
	return ret_ok;
}
static ret_t
config_server (cherokee_server_t *srv)
{
	ret_t                  ret;
	cherokee_config_node_t conf;
	cherokee_buffer_t      buf       = CHEROKEE_BUF_INIT;
	cherokee_buffer_t      rrd_dir   = CHEROKEE_BUF_INIT;
	cherokee_buffer_t      rrd_bin   = CHEROKEE_BUF_INIT;
	cherokee_buffer_t      fake;

	/* Generate the password
	 */
	if (unsecure == 0) {
		ret = generate_admin_password (&password);
		if (ret != ret_ok)
			return ret;
	}

	/* Configure the embedded server
	 */
	if (scgi_port > 0) {
		ret = find_empty_port (scgi_port, &scgi_port);
	} else {
		ret = remove_old_socket (DEFAULT_UNIX_SOCKET);
	}
	if (ret != ret_ok) {
		return ret_error;
	}

	cherokee_buffer_add_va  (&buf, "server!bind!1!port = %d\n", port);
	cherokee_buffer_add_str (&buf, "server!ipv6 = 1\n");
	cherokee_buffer_add_str (&buf, "server!max_connection_reuse = 0\n");
	cherokee_buffer_add_va  (&buf, "server!iocache = %d\n", iocache);

	if (bind_to) {
		cherokee_buffer_add_va (&buf, "server!bind!1!interface = %s\n", bind_to);
	}

	if (thread_num != -1) {
		cherokee_buffer_add_va (&buf, "server!thread_number = %d\n", thread_num);
	}

	cherokee_buffer_add_str (&buf, "vserver!1!nick = default\n");
	cherokee_buffer_add_va  (&buf, "vserver!1!document_root = %s\n", document_root);

	if (scgi_port <= 0) {
		cherokee_buffer_add_va  (&buf,
					 "source!1!nick = app-logic\n"
					 "source!1!type = interpreter\n"
					 "source!1!timeout = " TIMEOUT "\n"
					 "source!1!host = %s\n"
					 "source!1!interpreter = %s/server.py %s %s %s\n"
					 "source!1!env_inherited = 1\n",
					 DEFAULT_UNIX_SOCKET, document_root,
					 DEFAULT_UNIX_SOCKET, config_file,
					 (debug) ? "-x" : "");

	} else {
		cherokee_buffer_add_va  (&buf,
					 "source!1!nick = app-logic\n"
					 "source!1!type = interpreter\n"
					 "source!1!timeout = " TIMEOUT "\n"
					 "source!1!host = localhost:%d\n"
					 "source!1!interpreter = %s/server.py %d %s %s\n"
					 "source!1!env_inherited = 1\n",
					 scgi_port, document_root,
					 scgi_port, config_file,
					 (debug) ? "-x" : "");
	}

	if (debug) {
		cherokee_buffer_add_str  (&buf, "source!1!debug = 1\n");
	}

	cherokee_buffer_add_str  (&buf,
				  RULE_PRE "1!match = default\n"
				  RULE_PRE "1!handler = scgi\n"
				  RULE_PRE "1!timeout = " TIMEOUT "\n"
				  RULE_PRE "1!handler!balancer = round_robin\n"
				  RULE_PRE "1!handler!balancer!source!1 = 1\n");

	cherokee_buffer_add_str  (&buf, RULE_PRE "1!handler!env!CTK_COOKIE = ");
	generate_admin_password  (&buf);
	cherokee_buffer_add_char (&buf, '\n');

	if (! debug) {
		cherokee_buffer_add_str (&buf, RULE_PRE "1!encoder!gzip = 1\n");
	}

	if ((unsecure == 0) &&
	    (!cherokee_buffer_is_empty (&password)))
	{
		cherokee_buffer_add_va (&buf,
					RULE_PRE "1!auth = authlist\n"
					RULE_PRE "1!auth!methods = digest\n"
					RULE_PRE "1!auth!realm = Cherokee-admin\n"
					RULE_PRE "1!auth!list!1!user = admin\n"
					RULE_PRE "1!auth!list!1!password = %s\n",
					password.buf);
	}

	cherokee_buffer_add_str (&buf,
				 RULE_PRE "2!match = directory\n"
				 RULE_PRE "2!match!directory = /about\n"
				 RULE_PRE "2!handler = server_info\n");

	cherokee_buffer_add_str (&buf,
				 RULE_PRE "3!match = directory\n"
				 RULE_PRE "3!match!directory = /static\n"
				 RULE_PRE "3!handler = file\n"
				 RULE_PRE "3!expiration = time\n"
				 RULE_PRE "3!expiration!time = 30d\n");

	cherokee_buffer_add_va  (&buf,
				 RULE_PRE "4!match = request\n"
				 RULE_PRE "4!match!request = ^/favicon.ico$\n"
				 RULE_PRE "4!document_root = %s/static/images\n"
				 RULE_PRE "4!handler = file\n"
				 RULE_PRE "4!expiration = time\n"
				 RULE_PRE "4!expiration!time = 30d\n",
				 document_root);

	cherokee_buffer_add_va  (&buf,
				 RULE_PRE "5!match = directory\n"
				 RULE_PRE "5!match!directory = /icons_local\n"
				 RULE_PRE "5!handler = file\n"
				 RULE_PRE "5!document_root = %s\n"
				 RULE_PRE "5!expiration = time\n"
				 RULE_PRE "5!expiration!time = 30d\n",
				 CHEROKEE_ICONSDIR);

	cherokee_buffer_add_va  (&buf,
				 RULE_PRE "6!match = directory\n"
				 RULE_PRE "6!match!directory = /CTK\n"
				 RULE_PRE "6!handler = file\n"
				 RULE_PRE "6!document_root = %s/CTK/static\n"
				 RULE_PRE "6!expiration = time\n"
				 RULE_PRE "6!expiration!time = 30d\n",
				 document_root);

	/* Embedded help
	 */
	cherokee_buffer_add_va  (&buf,
				 RULE_PRE "7!match = and\n"
				 RULE_PRE "7!match!left = directory\n"
				 RULE_PRE "7!match!left!directory = /help\n"
				 RULE_PRE "7!match!right = not\n"
				 RULE_PRE "7!match!right!right = extensions\n"
				 RULE_PRE "7!match!right!right!extensions = html\n"
				 RULE_PRE "7!handler = file\n");

	cherokee_buffer_add_va  (&buf,
				 RULE_PRE "8!match = fullpath\n"
				 RULE_PRE "8!match!fullpath!1 = /static/help_404.html\n"
				 RULE_PRE "8!handler = file\n"
				 RULE_PRE "8!document_root = %s\n", document_root);

	cherokee_buffer_add_va  (&buf,
				 RULE_PRE "9!match = and\n"
				 RULE_PRE "9!match!left = directory\n"
				 RULE_PRE "9!match!left!directory = /help\n"
				 RULE_PRE "9!match!right = not\n"
				 RULE_PRE "9!match!right!right = exists\n"
				 RULE_PRE "9!match!right!right!match_any = 1\n"
				 RULE_PRE "9!handler = redir\n"
				 RULE_PRE "9!handler!rewrite!1!show = 1\n"
				 RULE_PRE "9!handler!rewrite!1!substring = /static/help_404.html\n");

	cherokee_buffer_add_va  (&buf,
				 RULE_PRE "10!match = directory\n"
				 RULE_PRE "10!match!directory = /help\n"
				 RULE_PRE "10!match!final = 0\n"
				 RULE_PRE "10!document_root = %s\n", CHEROKEE_DOCDIR);

	/* GZip
	 */
	if (! debug) {
		cherokee_buffer_add_va (&buf,
					RULE_PRE "15!match = extensions\n"
					RULE_PRE "15!match!extensions = css,js,html\n"
					RULE_PRE "15!match!final = 0\n"
					RULE_PRE "15!encoder!gzip = 1\n");
	}

	/* RRDtool graphs
	 */
	cherokee_config_node_init (&conf);
	cherokee_buffer_fake (&fake, config_file, strlen(config_file));

	ret = cherokee_config_reader_parse (&conf, &fake);
	if (ret == ret_ok) {
		cherokee_config_node_copy (&conf, "server!collector!rrdtool_path", &rrd_bin);
		cherokee_config_node_copy (&conf, "server!collector!database_dir", &rrd_dir);
	}

	if (! cherokee_buffer_is_empty (&rrd_bin)) {
		cherokee_buffer_add_va  (&buf,
					 RULE_PRE "20!handler!rrdtool_path = %s\n", rrd_bin.buf);
	}

	if (! cherokee_buffer_is_empty (&rrd_dir)) {
		cherokee_buffer_add_va  (&buf,
					 RULE_PRE "20!handler!database_dir = %s\n", rrd_dir.buf);
	}

	cherokee_buffer_add_str (&buf,
				 RULE_PRE "20!match = directory\n"
				 RULE_PRE "20!match!directory = /graphs\n"
				 RULE_PRE "20!handler = render_rrd\n"
				 RULE_PRE "20!expiration = epoch\n"
				 RULE_PRE "20!expiration!caching = no-cache\n"
				 RULE_PRE "20!expiration!caching!no-store = 1\n");

	cherokee_buffer_add_str (&buf, RULE_PRE "20!document_root = ");
	cherokee_tmp_dir_copy   (&buf);
	cherokee_buffer_add_va  (&buf, "/cherokee/rrd-cache\n");

	/* MIME types
	 */
	cherokee_buffer_add_str (&buf,
				 "mime!text/javascript!extensions = js\n"
				 "mime!text/css!extensions = css\n"
				 "mime!image/png!extensions = png\n"
				 "mime!image/jpeg!extensions = jpeg,jpg\n"
				 "mime!image/svg+xml!extensions = svg,svgz\n"
				 "mime!image/gif!extensions = gif\n");

	ret = cherokee_server_read_config_string (srv, &buf);
	if (ret != ret_ok) {
		PRINT_ERROR_S ("Could not initialize the server\n");
		return ret;
	}

	cherokee_config_node_mrproper (&conf);

	cherokee_buffer_mrproper (&rrd_bin);
	cherokee_buffer_mrproper (&rrd_dir);
	cherokee_buffer_mrproper (&buf);

	return ret_ok;
}
static ret_t
parse (cherokee_handler_ssi_t *hdl,
       cherokee_buffer_t      *in,
       cherokee_buffer_t      *out)
{
	ret_t              ret;
	char              *p, *q;
	char              *begin;
	int                re;
	cuint_t            len;
	operations_t       op;
	path_type_t        path;
	struct stat        info;
	cherokee_boolean_t ignore;
	cherokee_buffer_t  key     = CHEROKEE_BUF_INIT;
	cherokee_buffer_t  val     = CHEROKEE_BUF_INIT;
	cherokee_buffer_t  pair    = CHEROKEE_BUF_INIT;
	cherokee_buffer_t  fpath   = CHEROKEE_BUF_INIT;

	q = in->buf;

	while (true) {
		begin = q;

		/* Check the end
		 */
		if (q >= in->buf + in->len)
			break;

		/* Find next SSI tag
		 */
		p = strstr (q, "<!--#");
		if (p == NULL) {
			cherokee_buffer_add (out, begin, (in->buf + in->len) - begin);
			ret = ret_ok;
			goto out;
		}

		q = strstr (p + 5, "-->");
		if (q == NULL) {
			ret = ret_error;
			goto out;
		}

		len = q - p;
		len -= 5;

		cherokee_buffer_clean (&key);
		cherokee_buffer_add (&key, p+5, len);
		cherokee_buffer_trim (&key);

		q += 3;
		TRACE(ENTRIES, "Found key '%s'\n", key.buf);

		/* Add the previous chunk
		 */
		cherokee_buffer_add (out, begin, p - begin);

		/* Check element
		 */
		op     = op_none;
		ignore = false;

		if (strncmp (key.buf, "include", 7) == 0) {
			op  = op_include;
			len = 7;
		} else if (strncmp (key.buf, "fsize", 5) == 0) {
			op  = op_size;
			len = 5;
		} else if (strncmp (key.buf, "flastmod", 8) == 0) {
			op  = op_lastmod;
			len = 8;
		} else {
			LOG_ERROR (CHEROKEE_ERROR_HANDLER_SSI_PROPERTY, key.buf);
		}

		/* Deeper parsing
		 */
		path = path_none;

		switch (op) {
		case op_size:
		case op_include:
		case op_lastmod:
			/* Read a property key
			 */
			cherokee_buffer_move_to_begin (&key, len);
			cherokee_buffer_trim (&key);

			cherokee_buffer_clean (&pair);
			get_pair (&key, &pair);

			cherokee_buffer_drop_ending (&key, pair.len);
			cherokee_buffer_trim (&key);

			/* Parse the property
			 */
			if (strncmp (pair.buf, "file=", 5) == 0) {
				path = path_file;
				len  = 5;
			} else if (strncmp (pair.buf, "virtual=", 8) == 0) {
				path = path_virtual;
				len  = 8;
			}

			cherokee_buffer_clean (&val);
			get_val (pair.buf + len, &val);

			cherokee_buffer_clean (&fpath);

			switch (path) {
			case path_file:
				cherokee_buffer_add_buffer (&fpath, &hdl->dir);
				cherokee_buffer_add_char   (&fpath, '/');
				cherokee_buffer_add_buffer (&fpath, &val);

				TRACE(ENTRIES, "Path: file '%s'\n", fpath.buf);
				break;
			case path_virtual:
				cherokee_buffer_add_buffer (&fpath, &HANDLER_VSRV(hdl)->root);
				cherokee_buffer_add_char   (&fpath, '/');
				cherokee_buffer_add_buffer (&fpath, &val);

				TRACE(ENTRIES, "Path: virtual '%s'\n", fpath.buf);
				break;
			default:
				ignore = true;
				SHOULDNT_HAPPEN;
			}

			/* Path security check: ensure that the file
			 * to include is inside the document root.
			 */
			if (! cherokee_buffer_is_empty (&fpath)) {
				cherokee_path_short (&fpath);

				if (fpath.len < HANDLER_VSRV(hdl)->root.len) {
					ignore = true;

				}  else {
					re = strncmp (fpath.buf,
					              HANDLER_VSRV(hdl)->root.buf,
					              HANDLER_VSRV(hdl)->root.len);
					if (re != 0) {
						ignore = true;
					}
				}
			}

			/* Perform the operation
			 */
			if (! ignore) {
				switch (op) {
				case op_include: {
					cherokee_buffer_t file_content = CHEROKEE_BUF_INIT;

					ret = cherokee_buffer_read_file (&file_content, fpath.buf);
					if (unlikely (ret != ret_ok)) {
						cherokee_buffer_mrproper (&file_content);
						ret = ret_error;
						goto out;
					}

					TRACE(ENTRIES, "Including file '%s'\n", fpath.buf);

					ret = parse (hdl, &file_content, out);
					if (unlikely (ret != ret_ok)) {
						cherokee_buffer_mrproper (&file_content);
						ret = ret_error;
						goto out;
					}

					cherokee_buffer_mrproper (&file_content);
					break;
				}

				case op_size:
					TRACE(ENTRIES, "Including file size '%s'\n", fpath.buf);
					re = cherokee_stat (fpath.buf, &info);
					if (re >=0) {
						cherokee_buffer_add_ullong10 (out, info.st_size);
					}
					break;

				case op_lastmod:
					TRACE(ENTRIES, "Including file modification date '%s'\n", fpath.buf);
					re = cherokee_stat (fpath.buf, &info);
					if (re >= 0) {
						struct tm *ltime;
						struct tm  ltime_buf;
						char       tmp[50];

						ltime = cherokee_localtime (&info.st_mtime, &ltime_buf);
						if (ltime != NULL) {
							strftime (tmp, sizeof(tmp), "%d-%b-%Y %H:%M", ltime);
							cherokee_buffer_add (out, tmp, strlen(tmp));
						}
					}
					break;
				default:
					SHOULDNT_HAPPEN;
				}
			} /* !ignore */

			break;
		default:
			SHOULDNT_HAPPEN;
		} /* switch(op) */
	} /* while */

	ret = ret_ok;

out:
	cherokee_buffer_mrproper (&key);
	cherokee_buffer_mrproper (&val);
	cherokee_buffer_mrproper (&pair);
	cherokee_buffer_mrproper (&fpath);

	return ret;
}
Exemple #17
0
void
cherokee_trace_do_trace (const char *entry, const char *file, int line, const char *func, const char *fmt, ...)
{
	ret_t                  ret;
	char                  *p;
	char                  *lentry;
	char                  *lentry_end;
	va_list                args;
	cherokee_connection_t *conn;
	cherokee_buffer_t     *trace_modules = &trace.modules;
	cherokee_boolean_t     do_log        = false;
	cherokee_buffer_t      entries       = CHEROKEE_BUF_INIT;

	/* Prevents loops
	 */
	if (disabled) {
		return;
	}

	disabled = true;

	/* Return ASAP if nothing is being traced
	 */
	if (cherokee_buffer_is_empty (&trace.modules)) {
		goto out;
	}

	/* Check the connection source, if possible
	 */
	if (trace.from_filter != NULL) {
		conn = CONN (CHEROKEE_THREAD_PROP_GET (thread_connection_ptr));

		/* No conn, no trace entry
		 */
		if (conn == NULL) {
			goto out;
		}

		if (conn->socket.socket < 0) {
			goto out;
		}

		/* Skip the trace if the conn doesn't match
		 */
		ret = cherokee_access_ip_match (trace.from_filter, &conn->socket);
		if (ret != ret_ok) {
			goto out;
		}
	}

	/* Also, check for 'all'
	 */
	p = strstr (trace_modules->buf, "all");
	if (p == NULL) {
		/* Parse the In-code module string
		 */
		cherokee_buffer_add (&entries, entry, strlen(entry));

		for (lentry = entries.buf;;) {
			lentry_end = strchr (lentry, ',');
			if (lentry_end) *lentry_end = '\0';

			/* Check the type
			 */
			p = strstr (trace_modules->buf, lentry);
			if (p) {
				char *tmp = p + strlen(lentry);
				if ((*tmp == '\0') || (*tmp == ',') || (*tmp == ' '))
					do_log = true;
			}

			if ((lentry_end == NULL) || (do_log))
				break;

			lentry = lentry_end + 1;
		}

		/* Return if trace entry didn't match with the configured list
		 */
		if (! do_log) {
			goto out;
		}
	}

	/* Format the message and log it:
	 * 'entries' is not needed at this stage, reuse it
	 */
	cherokee_buffer_clean (&entries);
	if (trace.print_thread) {
		int        len;
		char       tmp[32+1];
		static int longest_len = 0;

		len = snprintf (tmp, 32+1, "%llX", (unsigned long long) CHEROKEE_THREAD_SELF);
		longest_len = MAX (longest_len, len);

		cherokee_buffer_add_str    (&entries, "{0x");
		cherokee_buffer_add_char_n (&entries, '0', longest_len - len);
		cherokee_buffer_add        (&entries, tmp, len);
		cherokee_buffer_add_str    (&entries, "} ");
	}

	if (trace.print_time) {
		cherokee_buffer_add_char (&entries, '[');
		cherokee_buf_add_bogonow (&entries, true);
		cherokee_buffer_add_str  (&entries, "] ");
	}

	cherokee_buffer_add_va (&entries, "%18s:%04d (%30s): ", file, line, func);

	va_start (args, fmt);
	cherokee_buffer_add_va_list (&entries, (char *)fmt, args);
	va_end (args);

	if (trace.use_syslog) {
		cherokee_syslog (LOG_DEBUG, &entries);
	} else {
#ifdef HAVE_FLOCKFILE
		flockfile (stdout);
#endif
		fprintf (stdout, "%s", entries.buf);
#ifdef HAVE_FUNLOCKFILE
		funlockfile (stdout);
#endif
	}

out:
	cherokee_buffer_mrproper (&entries);
	disabled = false;
}