Ejemplo n.º 1
0
PANCAKE_API Byte *PancakeNetworkGetInterfaceName(struct sockaddr *addr) {
	Byte *name;

	PancakeAssert(addr->sa_family == AF_INET || addr->sa_family == AF_INET6 || addr->sa_family == AF_UNIX);

	switch(addr->sa_family) {
		case AF_INET: {
			Byte textAddress[INET_ADDRSTRLEN + 1];

			inet_ntop(AF_INET, &((struct sockaddr_in*) addr)->sin_addr, textAddress, INET_ADDRSTRLEN);

			// IPv4:<address>:<port>
			name = PancakeAllocate(sizeof("IPv4::12345") + INET_ADDRSTRLEN);
			sprintf(name, "IPv4:%s:%i", textAddress, (Int32) ntohs(((struct sockaddr_in*) addr)->sin_port));
		} break;
		case AF_INET6: {
			Byte textAddress[INET6_ADDRSTRLEN + 1];

			inet_ntop(AF_INET6, &((struct sockaddr_in6*) addr)->sin6_addr, textAddress, INET6_ADDRSTRLEN);

			// IPv6:[<address>]:<port>
			name = PancakeAllocate(sizeof("IPv6:[]:12345") + INET6_ADDRSTRLEN);
			sprintf(name, "IPv6:[%s]:%i", textAddress, (Int32) ntohs(((struct sockaddr_in6*) addr)->sin6_port));
		} break;
		case AF_UNIX: {
			// UNIX:<address>
			name = PancakeAllocate(sizeof("UNIX:") + sizeof(((struct sockaddr_un*) addr)->sun_path));
			sprintf(name, "UNIX:%s", ((struct sockaddr_un*) addr)->sun_path);
		} break;
	}

	return name;
}
Ejemplo n.º 2
0
PANCAKE_API UByte PancakeNetworkInterfaceConfiguration(UByte step, config_setting_t *setting, PancakeConfigurationScope **scope) {
	switch(step) {
		case PANCAKE_CONFIGURATION_INIT: {
			PancakeSocket *socket = PancakeAllocate(sizeof(PancakeSocket));

			/* Used for backlog storage */
			socket->data = (void*) 0x1;
			socket->fd = -1;
			socket->localAddress = PancakeAllocate(sizeof(struct sockaddr));
			socket->onRead = NULL;
			socket->onWrite = NULL;
			socket->onRemoteHangup = NULL;
			socket->flags = 0;
			socket->layer = NULL;

			socket->localAddress->sa_family = 0;
			memset(socket->localAddress->sa_data, 0, sizeof(socket->localAddress->sa_data));

			setting->hook = (void*) socket;
		} break;
		case PANCAKE_CONFIGURATION_DTOR: {
			PancakeSocket *socket = (PancakeSocket*) setting->hook;

			if(socket->fd != -1) {
				close(socket->fd);
			}

			PancakeFree(socket->localAddress);
			PancakeFree(socket);

			// Make library happy
			setting->hook = NULL;
		} break;
	}

	return 1;
}
Ejemplo n.º 3
0
STATIC UByte PancakeAuthenticationGroupConfiguration(UByte step, config_setting_t *setting, PancakeConfigurationScope **scope) {
	PancakeAuthenticationConfiguration *config;

	if(step == PANCAKE_CONFIGURATION_INIT) {
		config = PancakeAllocate(sizeof(PancakeAuthenticationConfiguration));

		setting->hook = (void*) config;
		config->backend = NULL;
		config->backendData = NULL;
	} else {
		config = (PancakeAuthenticationConfiguration*) setting->hook;
		PancakeFree(config);
	}

	return 1;
}
Ejemplo n.º 4
0
PANCAKE_API PancakeSchedulerEvent *PancakeSchedule(UNative time, PancakeSchedulerEventCallback callback, void *arg) {
	PancakeSchedulerEvent *event;

	if(unusedEvents) {
		// Use cached event instance
		event = unusedEvents;

		CDL_DELETE(unusedEvents, unusedEvents);
	} else {
		// Allocate new event
		event = PancakeAllocate(sizeof(PancakeSchedulerEvent));
	}

	event->time = time;
	event->callback = callback;
	event->arg = arg;

	if(events) {
		if(events->prev->time <= time) {
			CDL_PREPEND_ELEM(events, events, event);

			events = event->next;
		} else if(events->time >= time) {
			CDL_PREPEND(events, event);
		} else {
			PancakeSchedulerEvent *ev;

			// Iterate through events and find place for new event
			CDL_FOREACH(events, ev) {
				if(ev->time == time) {
					CDL_PREPEND_ELEM(events, ev->next, event);
					break;
				} else if(ev->time < time && ev->next->time >= time) {
					CDL_PREPEND_ELEM(events, ev->next, event);
					break;
				}
			}
		}
	} else {
STATIC UByte PancakeHTTPBasicAuthenticate(PancakeSocket *sock) {
	// Check whether authentication framework is active
	if(PancakeAuthenticationActiveConfiguration) {
		PancakeHTTPRequest *request = (PancakeHTTPRequest*) sock->data;
		PancakeHTTPHeader *header;

		// Check credentials provided by client
		if(request->authorization.length > 6) {
			UByte *authorization = sock->readBuffer.value + request->authorization.offset;

			if(!memcmp(authorization, "Basic ", 6)) {
				UByte decoded[request->authorization.length - 6], *ptr;
				base64_decodestate state = {0};
				PancakeAuthenticationUserPassword client;
				UInt32 length;

				// Decode base64 user and password
				length = base64_decode_block(authorization + 6, request->authorization.length - 6, decoded, &state);
				ptr = memchr(decoded, ':', length);

				if(ptr != NULL) {
					client.user.value = decoded;
					client.user.length = ptr - decoded;

					if(ptr - decoded < length) {
						client.password.value = ptr + 1;
						client.password.length = decoded + length - (ptr + 1);
					} else {
						client.password.value = "";
						client.password.length = 0;
					}

					// Try authentication
					if(PancakeAuthenticate(PancakeAuthenticationActiveConfiguration, &client)) {
						return 1;
					}
				}
			}
		}

		// Build WWW-Authenticate header
		header = PancakeAllocate(sizeof(PancakeHTTPHeader));
		header->name.value = PancakeAllocate(sizeof("WWW-Authenticate") - 1);
		header->name.length = sizeof("WWW-Authenticate") - 1;
		memcpy(header->name.value, "WWW-Authenticate", sizeof("WWW-Authenticate") - 1);

		if(activeRealm) {
			header->value.length = sizeof("Basic realm=\"\"") - 1 + activeRealm->length;
			header->value.value = PancakeAllocate(header->value.length);
			memcpy(header->value.value + 5, " realm=\"", sizeof(" realm=\"") - 1);
			memcpy(header->value.value + 5 + sizeof(" realm=\"") - 1, activeRealm->value, activeRealm->length);
			header->value.value[header->value.length - 1] = '"';
		} else {
			header->value.length = sizeof("Basic") - 1;
			header->value.value = PancakeAllocate(sizeof("Basic") - 1);
		}

		memcpy(header->value.value, "Basic", 5);

		LL_APPEND(request->answerHeaders, header);

		// Throw 401 Unauthorized
		PancakeHTTPException(sock, 401);
		return 0;
	}

	return 1;
}