Esempio n. 1
0
static int handle_logtime_config(struct nlmsghdr *nl_hdr, struct request_hdr *nat64_hdr,
		struct request_logtime *request)
{
#ifdef BENCHMARK
	struct nl_buffer *buffer;
	int error;

	switch (nat64_hdr->operation) {
	case OP_DISPLAY:
		log_debug("Sending logs time to userspace.");

		buffer = nlbuffer_create(nl_socket, nl_hdr);
		if (!buffer)
			return respond_error(nl_hdr, -ENOMEM);

		error = logtime_iterate_and_delete(request->l3_proto, request->l4_proto,
				logtime_entry_to_userspace, buffer);
		error = (error >= 0) ? nlbuffer_close(buffer, error) : respond_error(nl_hdr, error);

		kfree(buffer);
		return error;
	default:
		log_err("Unknown operation: %d", nat64_hdr->operation);
		return respond_error(nl_hdr, -EINVAL);
	}
#else
	log_err("Benchmark was not enabled during compilation.");
	return -EINVAL;
#endif
}
Esempio n. 2
0
static	int	
routeQuery(ROUTER *instance, void *session, GWBUF *queue)
{
WEB_SESSION	*wsession = (WEB_SESSION *)session;
char		*ptr;
int		i, found = 0;
char		*url;

	if ((url = gwbuf_get_property(queue, "URL")) == NULL)
	{
		respond_error(wsession, 404, "No URL available");
	}

	ptr = strrchr(url, '/');
	if (ptr)
		ptr++;
	else
		ptr = url;
	for (i = 0; pages[i].page; i++)
	{
		if (!strcmp(ptr, pages[i].page))
		{
			(pages[i].fcn)(wsession);
			found = 1;
		}
	}
	if (!found)
		respond_error(wsession, 404, "Unrecognised URL received");
	gwbuf_free(queue);
	return 0;
}
Esempio n. 3
0
static int handle_session_config(struct nlmsghdr *nl_hdr, struct request_hdr *nat64_hdr,
		struct request_session *request)
{
	__u64 count;
	int error;

	if (nat64_is_stateless()) {
		log_err("SIIT doesn't have session tables.");
		return -EINVAL;
	}

	switch (nat64_hdr->operation) {
	case OP_DISPLAY:
		return handle_session_display(nl_hdr, request);

	case OP_COUNT:
		log_debug("Returning session count.");
		error = sessiondb_count(request->l4_proto, &count);
		if (error)
			return respond_error(nl_hdr, error);
		return respond_setcfg(nl_hdr, &count, sizeof(count));

	default:
		log_err("Unknown operation: %d", nat64_hdr->operation);
		return respond_error(nl_hdr, -EINVAL);
	}
}
Esempio n. 4
0
static int handle_pool6_config(struct nlmsghdr *nl_hdr, struct request_hdr *jool_hdr,
		union request_pool6 *request)
{
	__u64 count;
	int error;

	switch (jool_hdr->operation) {
	case OP_DISPLAY:
		return handle_pool6_display(nl_hdr, request);

	case OP_COUNT:
		log_debug("Returning IPv6 prefix count.");
		error = pool6_count(&count);
		if (error)
			return respond_error(nl_hdr, error);
		return respond_setcfg(nl_hdr, &count, sizeof(count));

	case OP_ADD:
	case OP_UPDATE:
		if (verify_superpriv())
			return respond_error(nl_hdr, -EPERM);

		log_debug("Adding a prefix to the IPv6 pool.");

		return respond_error(nl_hdr, pool6_add(&request->add.prefix));

	case OP_REMOVE:
		if (verify_superpriv())
			return respond_error(nl_hdr, -EPERM);

		log_debug("Removing a prefix from the IPv6 pool.");
		error = pool6_remove(&request->remove.prefix);
		if (error)
			return respond_error(nl_hdr, error);

		if (nat64_is_stateful() && !request->flush.quick)
			error = sessiondb_delete_by_prefix6(&request->remove.prefix);

		return respond_error(nl_hdr, error);

	case OP_FLUSH:
		if (verify_superpriv())
			return respond_error(nl_hdr, -EPERM);

		log_debug("Flushing the IPv6 pool...");
		error = pool6_flush();
		if (error)
			return respond_error(nl_hdr, error);

		if (nat64_is_stateful() && !request->flush.quick)
			error = sessiondb_flush();

		return respond_error(nl_hdr, error);

	default:
		log_err("Unknown operation: %d", jool_hdr->operation);
		return respond_error(nl_hdr, -EINVAL);
	}
}
Esempio n. 5
0
static int handle_rfc6791_config(struct nlmsghdr *nl_hdr, struct request_hdr *nat64_hdr,
		union request_pool4 *request)
{
	__u64 count;
	int error;

	if (nat64_is_stateful()) {
		log_err("RFC 6791 does not apply to Stateful NAT64.");
		return -EINVAL;
	}

	switch (nat64_hdr->operation) {
	case OP_DISPLAY:
		return handle_pool6791_display(nl_hdr, request);

	case OP_COUNT:
		log_debug("Returning IPv4 address count.");
		error = rfc6791_count(&count);
		if (error)
			return respond_error(nl_hdr, error);
		return respond_setcfg(nl_hdr, &count, sizeof(count));

	case OP_ADD:
		if (verify_superpriv())
			return respond_error(nl_hdr, -EPERM);

		log_debug("Adding an address to the IPv4 pool.");
		return respond_error(nl_hdr, rfc6791_add(&request->add.addrs));

	case OP_REMOVE:
		if (verify_superpriv())
			return respond_error(nl_hdr, -EPERM);

		log_debug("Removing an address from the IPv4 pool.");

		error = rfc6791_remove(&request->remove.addrs);
		if (error)
			return respond_error(nl_hdr, error);

		return respond_error(nl_hdr, error);

	case OP_FLUSH:
		if (verify_superpriv()) {
			return respond_error(nl_hdr, -EPERM);
		}

		log_debug("Flushing the IPv4 pool...");
		error = rfc6791_flush();
		if (error)
			return respond_error(nl_hdr, error);

		return respond_error(nl_hdr, error);

	default:
		log_err("Unknown operation: %d", nat64_hdr->operation);
		return respond_error(nl_hdr, -EINVAL);
	}
}
Esempio n. 6
0
static int handle_pool4_add(struct nlmsghdr *nl_hdr, union request_pool4 *request)
{
	if (verify_superpriv())
		return respond_error(nl_hdr, -EPERM);

	log_debug("Adding elements to the IPv4 pool.");

	return respond_error(nl_hdr, pool4db_add(request->add.mark,
			request->add.proto, &request->add.addrs,
			&request->add.ports));
}
Esempio n. 7
0
/**
 * Gets called by "netlink_rcv_skb" when the userspace application wants to interact with us.
 *
 * @param skb packet received from userspace.
 * @param nlh message's metadata.
 * @return result status.
 */
static int handle_netlink_message(struct sk_buff *skb_in, struct nlmsghdr *nl_hdr)
{
	struct request_hdr *jool_hdr;
	void *request;
	int error;

	if (nl_hdr->nlmsg_type != MSG_TYPE_JOOL) {
		log_debug("Expecting %#x but got %#x.", MSG_TYPE_JOOL, nl_hdr->nlmsg_type);
		return -EINVAL;
	}

	jool_hdr = NLMSG_DATA(nl_hdr);
	request = jool_hdr + 1;

	error = validate_version(jool_hdr);
	if (error)
		return respond_error(nl_hdr, error);

	switch (jool_hdr->mode) {
	case MODE_POOL6:
		return handle_pool6_config(nl_hdr, jool_hdr, request);
		break;
	case MODE_POOL4:
		return handle_pool4_config(nl_hdr, jool_hdr, request);
		break;
	case MODE_BIB:
		return handle_bib_config(nl_hdr, jool_hdr, request);
		break;
	case MODE_SESSION:
		return handle_session_config(nl_hdr, jool_hdr, request);
		break;
	case MODE_EAMT:
		return handle_eamt_config(nl_hdr, jool_hdr, request);
		break;
	case MODE_RFC6791:
		return handle_rfc6791_config(nl_hdr, jool_hdr, request);
		break;
	case MODE_BLACKLIST:
		return handle_blacklist_config(nl_hdr, jool_hdr, request);
		break;
	case MODE_LOGTIME:
		return handle_logtime_config(nl_hdr, jool_hdr, request);
		break;
	case MODE_GLOBAL:
		return handle_global_config(nl_hdr, jool_hdr, request);
		break;
	}

	log_err("Unknown configuration mode: %d", jool_hdr->mode);
	return respond_error(nl_hdr, -EINVAL);

}
Esempio n. 8
0
static int handle_global_config(struct nlmsghdr *nl_hdr, struct request_hdr *jool_hdr,
		union request_global *request)
{
	struct global_config response = { .mtu_plateaus = NULL };
	unsigned char *buffer;
	size_t buffer_len;
	bool disabled;
	int error;

	switch (jool_hdr->operation) {
	case OP_DISPLAY:
		log_debug("Returning 'Global' options.");

		error = config_clone(&response);
		if (error)
			goto end;

		disabled = xlat_is_nat64()
				? pool6_is_empty()
				: (pool6_is_empty() && eamt_is_empty());
		error = serialize_global_config(&response, disabled, &buffer, &buffer_len);
		if (error)
			goto end;

		error = respond_setcfg(nl_hdr, buffer, buffer_len);
		kfree(buffer);
		break;

	case OP_UPDATE:
		if (verify_superpriv())
			return respond_error(nl_hdr, -EPERM);

		log_debug("Updating 'Global' options.");

		buffer = (unsigned char *) (request + 1);
		buffer_len = jool_hdr->length - sizeof(*jool_hdr) - sizeof(*request);

		error = handle_global_update(request->update.type, buffer_len, buffer);
		break;

	default:
		log_err("Unknown operation: %d", jool_hdr->operation);
		error = -EINVAL;
	}

end:
	return respond_error(nl_hdr, error);
}
Esempio n. 9
0
static int handle_pool4_config(struct nlmsghdr *nl_hdr, struct request_hdr *jool_hdr,
		union request_pool4 *request)
{
	struct response_pool4_count counters;

	if (xlat_is_siit()) {
		log_err("SIIT doesn't have pool4.");
		return -EINVAL;
	}

	switch (jool_hdr->operation) {
	case OP_DISPLAY:
		return handle_pool4_display(nl_hdr, request);

	case OP_COUNT:
		log_debug("Returning IPv4 pool counters.");
		pool4db_count(&counters.tables, &counters.samples,
				&counters.taddrs);
		return respond_setcfg(nl_hdr, &counters, sizeof(counters));

	case OP_ADD:
		return handle_pool4_add(nl_hdr, request);

	case OP_REMOVE:
		return handle_pool4_rm(nl_hdr, request);

	case OP_FLUSH:
		return handle_pool4_flush(nl_hdr, request);

	default:
		log_err("Unknown operation: %d", jool_hdr->operation);
		return respond_error(nl_hdr, -EINVAL);
	}
}
Esempio n. 10
0
static int handle_blacklist_display(struct nlmsghdr *nl_hdr, union request_pool *request)
{
	struct nl_buffer *buffer;
	struct ipv4_prefix *offset;
	int error;

	buffer = nlbuffer_create(nl_socket, nl_hdr);
	if (!buffer)
		return respond_error(nl_hdr, -ENOMEM);

	offset = request->display.offset_set ? &request->display.offset : NULL;
	error = blacklist_for_each(pool_to_usr, buffer, offset);
	error = (error >= 0) ? nlbuffer_close(buffer, error) : respond_error(nl_hdr, error);

	kfree(buffer);
	return error;
}
Esempio n. 11
0
static int handle_eamt_config(struct nlmsghdr *nl_hdr, struct request_hdr *jool_hdr,
		union request_eamt *request)
{
	__u64 count;
	int error;

	if (xlat_is_nat64()) {
		log_err("Stateful NAT64 doesn't have an EAMT.");
		return -EINVAL;
	}

	switch (jool_hdr->operation) {
	case OP_DISPLAY:
		return handle_eamt_display(nl_hdr, request);

	case OP_COUNT:
		log_debug("Returning EAMT count.");
		error = eamt_count(&count);
		if (error)
			return respond_error(nl_hdr, error);
		return respond_setcfg(nl_hdr, &count, sizeof(count));

	case OP_TEST:
		return handle_eamt_test(nl_hdr, request);

	case OP_ADD:
		if (verify_superpriv())
			return respond_error(nl_hdr, -EPERM);

		log_debug("Adding EAMT entry.");
		return respond_error(nl_hdr, eamt_add(&request->add.prefix6,
				&request->add.prefix4, request->add.force));

	case OP_REMOVE:
		if (verify_superpriv())
			return respond_error(nl_hdr, -EPERM);

		log_debug("Removing EAMT entry.");
		return respond_error(nl_hdr, eamt_rm(
				request->rm.prefix6_set ? &request->rm.prefix6 : NULL,
				request->rm.prefix4_set ? &request->rm.prefix4 : NULL));

	case OP_FLUSH:
		if (verify_superpriv())
			return respond_error(nl_hdr, -EPERM);

		eamt_flush();
		return respond_error(nl_hdr, 0);

	default:
		log_err("Unknown operation: %d", jool_hdr->operation);
		return respond_error(nl_hdr, -EINVAL);
	}
}
Esempio n. 12
0
static int handle_pool6791_display(struct nlmsghdr *nl_hdr, union request_pool4 *request)
{
	struct nl_buffer *buffer;
	struct ipv4_prefix *prefix;
	int error;

	log_debug("Sending RFC6791 pool to userspace.");

	buffer = nlbuffer_create(nl_socket, nl_hdr);
	if (!buffer)
		return respond_error(nl_hdr, -ENOMEM);

	prefix = request->display.prefix_set ? &request->display.prefix : NULL;
	error = rfc6791_for_each(pool4_to_usr, buffer, prefix);
	error = (error >= 0) ? nlbuffer_close(buffer, error) : respond_error(nl_hdr, error);

	kfree(buffer);
	return error;
}
Esempio n. 13
0
static int handle_bib_display(struct nlmsghdr *nl_hdr, struct request_bib *request)
{
	struct nl_buffer *buffer;
	struct ipv4_transport_addr *addr4;
	int error;

	log_debug("Sending BIB to userspace.");

	buffer = nlbuffer_create(nl_socket, nl_hdr);
	if (!buffer)
		return respond_error(nl_hdr, -ENOMEM);

	addr4 = request->display.addr4_set ? &request->display.addr4 : NULL;
	error = bibdb_iterate_by_ipv4(request->l4_proto, bib_entry_to_userspace, buffer, addr4);
	error = (error >= 0) ? nlbuffer_close(buffer, error) : respond_error(nl_hdr, error);

	kfree(buffer);
	return error;
}
Esempio n. 14
0
static int handle_pool4_rm(struct nlmsghdr *nl_hdr, union request_pool4 *request)
{
	int error;

	if (verify_superpriv())
		return respond_error(nl_hdr, -EPERM);

	log_debug("Removing elements from the IPv4 pool.");

	error = pool4db_rm(request->rm.mark, request->rm.proto,
			&request->rm.addrs, &request->rm.ports);

	if (xlat_is_nat64() && !request->rm.quick) {
		sessiondb_delete_taddr4s(&request->rm.addrs, &request->rm.ports);
		bibdb_delete_taddr4s(&request->rm.addrs, &request->rm.ports);
	}

	return respond_error(nl_hdr, error);
}
Esempio n. 15
0
static int handle_eamt_display(struct nlmsghdr *nl_hdr, union request_eamt *request)
{
	struct nl_buffer *buffer;
	struct ipv4_prefix *prefix4;
	int error;

	log_debug("Sending EAMT to userspace.");

	buffer = nlbuffer_create(nl_socket, nl_hdr);
	if (!buffer)
		return respond_error(nl_hdr, -ENOMEM);

	prefix4 = request->display.prefix4_set ? &request->display.prefix4 : NULL;
	error = eamt_for_each(eam_entry_to_userspace, buffer, prefix4);
	error = (error >= 0) ? nlbuffer_close(buffer, error) : respond_error(nl_hdr, error);

	kfree(buffer);
	return error;
}
Esempio n. 16
0
File: owl.c Progetto: eliasson/owl
//
// Action handler that tries to login the given user to Spotify
//
static void login_to_spotify_action(struct owl_state* state, char* username, char* password) {
    TRACE("Logging in to Spotify...\n");

    state->state = OWL_STATE_LOGGING_IN;

    const sp_error error = sp_session_login(state->spotify_state->session, username, password, 0, NULL);
    if(error != SP_ERROR_OK) {
        ERROR("Failed to login to Spotify: %s\n", sp_error_message(error));
        respond_error(state->http_request, OWL_HTTP_ERROR_LOGIN, sp_error_message(error));
    }
}
Esempio n. 17
0
static int handle_pool4_display(struct nlmsghdr *nl_hdr, union request_pool4 *request)
{
	struct nl_buffer *buffer;
	struct pool4_sample *offset = NULL;
	int error;

	log_debug("Sending IPv4 pool to userspace.");

	buffer = nlbuffer_create(nl_socket, nl_hdr);
	if (!buffer)
		return respond_error(nl_hdr, -ENOMEM);

	if (request->display.offset_set)
		offset = &request->display.offset;

	error = pool4db_foreach_sample(pool4_to_usr, buffer, offset);
	error = (error >= 0) ? nlbuffer_close(buffer, error) : respond_error(nl_hdr, error);

	kfree(buffer);
	return error;
}
Esempio n. 18
0
static int handle_eamt_test(struct nlmsghdr *nl_hdr, union request_eamt *request)
{
	struct in6_addr addr6;
	struct in_addr addr4;
	int error;

	log_debug("Translating address for the user.");
	if (request->test.addr_is_ipv6) {
		error = eamt_xlat_6to4(&request->test.addr.addr6, &addr4);
		if (error)
			return respond_error(nl_hdr, error);

		return respond_setcfg(nl_hdr, &addr4, sizeof(addr4));
	} else {
		error = eamt_xlat_4to6(&request->test.addr.addr4, &addr6);
		if (error)
			return respond_error(nl_hdr, error);

		return respond_setcfg(nl_hdr, &addr6, sizeof(addr6));
	}
}
Esempio n. 19
0
static int handle_blacklist_config(struct nlmsghdr *nl_hdr, struct request_hdr *jool_hdr,
		union request_pool *request)
{
	__u64 count;
	int error;

	if (xlat_is_nat64()) {
		log_err("Blacklist does not apply to Stateful NAT64.");
		return -EINVAL;
	}

	switch (jool_hdr->operation) {
	case OP_DISPLAY:
		log_debug("Sending Blacklist pool to userspace.");
		return handle_blacklist_display(nl_hdr, request);

	case OP_COUNT:
		log_debug("Returning address count in the Blacklist pool.");
		error = blacklist_count(&count);
		if (error)
			return respond_error(nl_hdr, error);
		return respond_setcfg(nl_hdr, &count, sizeof(count));

	case OP_ADD:
		if (verify_superpriv())
			return respond_error(nl_hdr, -EPERM);

		log_debug("Adding an address to the Blacklist pool.");
		return respond_error(nl_hdr, blacklist_add(&request->add.addrs));

	case OP_REMOVE:
		if (verify_superpriv())
			return respond_error(nl_hdr, -EPERM);

		log_debug("Removing an address from the Blacklist pool.");
		return respond_error(nl_hdr, blacklist_rm(&request->rm.addrs));

	case OP_FLUSH:
		if (verify_superpriv())
			return respond_error(nl_hdr, -EPERM);

		log_debug("Flushing the Blacklist pool...");
		return respond_error(nl_hdr, blacklist_flush());

	default:
		log_err("Unknown operation: %d", jool_hdr->operation);
		return respond_error(nl_hdr, -EINVAL);
	}
}
Esempio n. 20
0
static int handle_pool4_flush(struct nlmsghdr *nl_hdr, union request_pool4 *request)
{
	int error;

	if (verify_superpriv())
		return respond_error(nl_hdr, -EPERM);

	log_debug("Flushing the IPv4 pool...");
	error = pool4db_flush();

	/*
	 * Well, pool4db_flush only errors on memory allocation failures,
	 * so I guess clearing BIB and session even if pool4db_flush fails
	 * is a good idea.
	 */
	if (xlat_is_nat64() && !request->flush.quick) {
		sessiondb_flush();
		bibdb_flush();
	}

	return respond_error(nl_hdr, error);
}
Esempio n. 21
0
static int handle_session_display(struct nlmsghdr *nl_hdr, struct request_session *request)
{
	struct nl_buffer *buffer;
	struct ipv4_transport_addr *remote4 = NULL;
	struct ipv4_transport_addr *local4 = NULL;
	int error;

	log_debug("Sending session table to userspace.");

	buffer = nlbuffer_create(nl_socket, nl_hdr);
	if (!buffer)
		return respond_error(nl_hdr, -ENOMEM);

	if (request->display.connection_set) {
		remote4 = &request->display.remote4;
		local4 = &request->display.local4;
	}
	error = sessiondb_iterate_by_ipv4(request->l4_proto, session_entry_to_userspace, buffer,
			remote4, local4);
	error = (error >= 0) ? nlbuffer_close(buffer, error) : respond_error(nl_hdr, error);

	kfree(buffer);
	return error;
}
Esempio n. 22
0
File: owl.c Progetto: eliasson/owl
//
// -- Spotify callbacks ---------------------------------------------------------------------------
//
static void logged_in_callback(sp_session *session, sp_error error) {
    TRACE("logged_in_callback\n");
    struct owl_state* state = sp_session_userdata(session);

    if(error == SP_ERROR_OK) {
        state->state = OWL_STATE_IDLE;
        INFO("Logged in to Spotify!\n");
        respond_success(state->http_request);
    }
    else {
        state->state = OWL_STATE_INITIALIZED;
        ERROR("Failed to login to Spotify: %s\n", sp_error_message(error));

        respond_error(state->http_request, OWL_HTTP_ERROR_LOGIN, sp_error_message(error));
    }
}
Esempio n. 23
0
static int handle_bib_config(struct nlmsghdr *nl_hdr, struct request_hdr *nat64_hdr,
		struct request_bib *request)
{
	__u64 count;
	int error;

	if (nat64_is_stateless()) {
		log_err("SIIT doesn't have BIBs.");
		return -EINVAL;
	}

	switch (nat64_hdr->operation) {
	case OP_DISPLAY:
		return handle_bib_display(nl_hdr, request);

	case OP_COUNT:
		log_debug("Returning BIB count.");
		error = bibdb_count(request->l4_proto, &count);
		if (error)
			return respond_error(nl_hdr, error);
		return respond_setcfg(nl_hdr, &count, sizeof(count));

	case OP_ADD:
		if (verify_superpriv())
			return respond_error(nl_hdr, -EPERM);

		log_debug("Adding BIB entry.");
		return respond_error(nl_hdr, add_static_route(request));

	case OP_REMOVE:
		if (verify_superpriv())
			return respond_error(nl_hdr, -EPERM);

		log_debug("Removing BIB entry.");
		return respond_error(nl_hdr, delete_static_route(request));

	default:
		log_err("Unknown operation: %d", nat64_hdr->operation);
		return respond_error(nl_hdr, -EINVAL);
	}
}
Esempio n. 24
0
int respond_success(FILE * fp, long long length) {
    char str[32];
    sprintf(str, "%llu", length);
    return respond_error(fp, 0, str);
}
Esempio n. 25
0
File: owl.c Progetto: eliasson/owl
//
// Function called when a new HTTP request have been recieved.
//
static void http_handler(struct evhttp_request *request, void *userdata) {
    struct owl_state* state = userdata;

    // Setup general response headers
    struct evkeyvalq *headers = evhttp_request_get_output_headers(request);
    evhttp_add_header(headers, "Server", USER_AGENT);

    // Get the requested URI
    const char* uri = evhttp_request_get_uri(request);
    const int http_method = evhttp_request_get_command(request);

    if( http_method != EVHTTP_REQ_GET &&
            http_method != EVHTTP_REQ_PUT &&
            http_method != EVHTTP_REQ_POST) {
        evhttp_send_error(request, 501, "Not Implemented");
        return;
    }

    TRACE("Received HTTP request: %s (method %d)\n", uri, http_method);

    // Keep the request for async usage
    state->http_request = request;

    //
    // Retrieve application state (sync)
    if(string_starts_with(uri, "/api/state") && http_method == EVHTTP_REQ_GET) {
        state_action(state);
    }

    //
    // Shutdown owl application (async)
    else if(string_starts_with(uri, "/api/shutdown") && http_method == EVHTTP_REQ_GET) {
        shutdown_action(state);
    }

    //
    // Try to login to Spotify (async)
    else if(string_starts_with(uri, "/api/login") && http_method == EVHTTP_REQ_GET) {
        char* username = extract_uri_section(2, uri);
        char* password = extract_uri_section(3, uri);

        if(username != NULL && password != NULL) {
            login_to_spotify_action(state, username, password);
        }
        else {
            WARN("Could not extract username and password in order to login to Spotify!\n");
            respond_error(request, OWL_HTTO_ERROR_NO_LOGIN_DETAILS, "No username or password given");
        }
    }

    else if(string_starts_with(uri, "/api/login") && http_method == EVHTTP_REQ_POST) {
        TRACE("POST LOGIN\n");
        get_post_argument(request, "username");
        evhttp_send_error(request, 501, "Not Implemented");
    }

    //
    // Logout from spotify (async)
    else if(string_starts_with(uri, "/api/logout") && http_method == EVHTTP_REQ_GET) {
        if(state->state > OWL_STATE_LOGGING_IN && state->state < OWL_STATE_LOGGING_OUT)
            logout_from_spotify_action(state);
        else
            respond_success(request);
    }

    //
    // Clear the entire queue
    else if(string_starts_with(uri, "/api/queue/clear") && http_method == EVHTTP_REQ_GET) {
        if(state->state < OWL_STATE_IDLE || state->state > OWL_STATE_PLAYING) {
            respond_error(request, OWL_HTTP_ERROR_NOT_LOGGED_IN, "Operation not allowed when not logged in");
        }
        else {
            const int size = queue_size(state->spotify_state->queue);
            for(int i = 0; i < size; i++) {
                owl_track *track = pop_from_queue(state->spotify_state->queue);
                free_track(track);
            }
            respond_success(request);
        }
    }

    //
    // Get the current playback queue (sync)
    else if(string_starts_with(uri, "/api/queue") && http_method == EVHTTP_REQ_GET) {
        if(state->state < OWL_STATE_IDLE || state->state > OWL_STATE_PLAYING) {
            WARN("Operation not allowed at this state (%d)\n", state->state);
            respond_error(request, OWL_HTTP_ERROR_NOT_LOGGED_IN, "Operation not allowed when not logged in");
        }
        else {
            respond_with_queue(state->http_request, state->spotify_state->queue);
        }
    }

    //
    // Serve static file immediately
    else {
        // Create the buffer to retrn as content
        struct evbuffer *content_buffer = evbuffer_new();

        // If not a handler this is a static request
        char *static_file = (char *) malloc(strlen(doc_root) + strlen(uri) + 1);
        stpcpy(stpcpy(static_file, doc_root), uri);

        TRACE("Looking for static file: %s\n", static_file);

        bool file_exists = 1;
        struct stat st;
        if(stat(static_file, &st) == -1 || S_ISDIR(st.st_mode)) {
            file_exists = 0;
            evhttp_send_error(request, HTTP_NOTFOUND, "Not Found");
        }

        if(file_exists) {
            const int file_size = st.st_size;
            FILE *fp = fopen(static_file, "r");
            const char* content_type = resolve_content_type(static_file);

            evbuffer_add_file(content_buffer, fileno(fp), 0, file_size); // will close

            TRACE("Resolving content type for filename: %s to: %s\n", static_file, content_type);
            evhttp_add_header(headers, "Content-Type", content_type);
            evhttp_send_reply(request, HTTP_OK, "OK", content_buffer);
        }
        free(static_file);

        // Send the data
        evhttp_send_reply(request, HTTP_OK, USER_AGENT, content_buffer);

        // Free memrory
        evbuffer_free(content_buffer);
    }
    return;
}
Esempio n. 26
0
void handle_client(int fd, const char * userTest, const char * passTest) {
    FILE * fp = fdopen(fd, "w+");
    char * user, * pass, * path;
    long long initial;
    if (read_client_request(fp, &user, &pass, &path, &initial) < 0) {
        return;
    }
    if (strcmp(user, userTest) != 0 || strcmp(pass, passTest) != 0) {
        respond_error(fp, PROTOCOL_ERROR_AUTH, "Login incorrect.");
        goto handleError;
    }
#ifdef __linux__
    struct stat64 info;
    if (stat64(path, &info) < 0) {
#else
    struct stat info
    if (stat(path, &info) < 0) {
#endif
        respond_error(fp, PROTOCOL_ERROR_NO_FILE, "Could not stat file.");
        goto handleError;
    }
    if (S_ISDIR(info.st_mode)) {
        respond_error(fp, PROTOCOL_ERROR_NOT_FILE, "Could not send directory.");
        goto handleError;
    }
    if (initial > info.st_size) {
        respond_error(fp, PROTOCOL_ERROR_INVALID_INITIAL, "Invalid initial offset.");
        goto handleError;
    }
#ifdef __linux__
    FILE * readFile = fopen64(path, "r");
#else
    FILE * readfile = fopen(path, "r");
#endif
    if (!readFile) {
        perror("fopen");
        respond_error(fp, PROTOCOL_ERROR_INTERNAL, "fopen() failed");
        goto handleError;
    }
    
    if (respond_success(fp, info.st_size - initial) < 0) {
        fclose(readFile);
        goto handleError;
    }
    
    // read file from start offset
    fseek(readFile, initial, SEEK_SET);
    char buff[512];
    while (!feof(readFile)) {
        int got = fread(buff, 1, 512, readFile);
        if (got == 0) break;
        if (fwrite(buff, 1, got, fp) != got) {
            break;
        }
    }
    fclose(readFile);
    
handleError:
    fclose(fp);
    free(user);
    free(pass);
    free(path);
    return;
}

void sigchild_handler(int signal) {
    int status;
    wait(&status);
}