static int KprWebSocketServerValidateRequest(FskHeaders *requestHeaders, FskHeaders *responseHeaders)
{
	FskErr err;
	char *value;
	char *decoded = NULL;
	UInt32 len;
	int statusCode = 400;

	value = FskHeaderFind("Upgrade", requestHeaders);
	if (!value || FskStrCompareCaseInsensitive(value, "websocket") != 0) goto bail;

	value = FskHeaderFind("Connection", requestHeaders);
	if (!value || FskStrCompareCaseInsensitive(value, "Upgrade") != 0) goto bail;

	value = FskHeaderFind("Sec-WebSocket-Version", requestHeaders);
	if (!value || FskStrCompare(value, "13") != 0) {
		statusCode = 426;
		FskHeaderAddString("Sec-WebSocket-Version", "13", responseHeaders);
		goto bail;
	}

	value = FskHeaderFind("Sec-WebSocket-Key", requestHeaders);
	if (!value) goto bail;

	bailIfError(FskStrB64Decode(value, FskStrLen(value), &decoded, &len));
	if (len != 16) goto bail;

	statusCode = 101;

bail:
	FskMemPtrDispose(decoded);

	return statusCode;
}
FskErr lpcmPacketParserCanHandle(SDPMediaDescription mediaDescription, const char *encodingName)
{
	if (0 == FskStrCompareCaseInsensitive("L8", encodingName)) return 0;
	if (0 == FskStrCompareCaseInsensitive("L16", encodingName)) return 0;

	return kFskErrRTSPPacketParserUnsupportedFormat;
}
FskErr h263PacketParserCanHandle(SDPMediaDescription mediaDescription, const char *encodingName)
{
	
	if (0 == FskStrCompareCaseInsensitive("H263-1998", encodingName) ||
		0 == FskStrCompareCaseInsensitive("H263-2000", encodingName))
		return 0;

	return kFskErrRTSPPacketParserUnsupportedFormat;
}
Exemple #4
0
FskErr KprCoAPClientSendRequest(KprCoAPClient self, KprCoAPMessage message)
{
	FskErr err = kFskErrNone;
	const char *host = message->host;
	UInt16 port = message->port;
	KprCoAPClientResolver dest = self->resolvers;

	while (dest) {
		if (port == dest->port && FskStrCompareCaseInsensitive(host, dest->host) == 0) break;

		dest = dest->next;
	}

	if (dest) {
		if (KprCoAPClientResolverIsResolved(dest)) {
			err = KprCoAPClientStartRequest(self, dest->ipaddr, port, message);
		} else {
			err = KprCoAPClientResolverQueueMessage(dest, message);
		}
	} else {
		bailIfError(KprCoAPClientResolverNew(&dest, self, host, port, message));
		FskListAppend(&self->resolvers, dest);
	}

bail:
	return err;
}
// ------------------------------------------------------------------------
void *FskAssociativeArrayElementGet(FskAssociativeArray array, const char *name, void **value, UInt32 *valueSize, SInt32 *valueType)
{
	FskAssociativeArrayNameList		list;

	if (!array || !name)
		return NULL;

	// try to find the list of values associated with name
	list = array->arrayHead;
	while (list) {
		if (FskStrCompareCaseInsensitive(name, list->name) == 0) {
			if (value)
				*value = list->value;
			if (valueSize)
				*valueSize = list->valueSize;
			if (valueType)
				*valueType = list->valueType;
			return list->value;
		}
		list = list->next;
	}

	if (value)
		*value = NULL;
	if (valueSize)
		*valueSize = 0;
	if (valueType)
		*valueType = kFskUnknownType;

	return NULL;
}
Boolean amrReaderCanHandle(const char *mimeType)
{
	if (0 == FskStrCompareCaseInsensitive("audio/AMR", mimeType))
		return true;

	return false;
}
FskErr latmPacketParserCanHandle(SDPMediaDescription mediaDescription, const char *encodingName)
{
	Boolean canHandle = false;

	// We handle MP4A-LATM encoding
	if (0 != FskStrCompareCaseInsensitive("MP4A-LATM", encodingName)) goto bail;

	if (NULL != mediaDescription) {
		SDPAttribute attribute;
		attribute = SDPFindMediaAttribute(mediaDescription, "fmtp");
		if (NULL != attribute) {
			char *attr;
	
			// The config string must be present in the SDP (i.e. out of band)
			if (NULL != copyAttributeValue(attribute->value, "cpresent", &attr)) {
				canHandle = (0 == FskStrToNum(attr));
				FskMemPtrDispose(attr);
			}
			// Validate the configuration
			if (canHandle) {
				if (NULL != copyAttributeValue(attribute->value, "config", &attr)) {
					canHandle = validateConfig(attr, NULL, NULL, NULL, NULL, NULL);
					FskMemPtrDispose(attr);
				}
				else
					canHandle = false;
			}
		}
	}

bail:
	return canHandle ? 0 : kFskErrRTSPPacketParserUnsupportedFormat;
}
static Boolean KprWebSocketEndpointCheckHeaderValue(FskHeaders *response, char *name, char *bingo)
{
	char *value;
	
	value = FskHeaderFind(name, response);
	if (!value) return false;
	
	return (FskStrCompareCaseInsensitive(value, bingo) == 0);
}
Exemple #9
0
KprDebugMachine KprDebugFindMachine(KprDebug self, char* address)
{
	KprDebugMachine machine = NULL;
	for (machine = self->machine; machine; machine = machine->next) {
		if (!FskStrCompareCaseInsensitive(machine->address, address))
			return machine;
	}
	return NULL;
}
FskErr mp3ReaderGetFlags(void *readerState, void *track, UInt32 propertyID, FskMediaPropertyValue property)
{
	mp3Reader state = readerState;
	FskMediaPropertyValueRecord value;

	property->type = kFskMediaPropertyTypeInteger;
	property->value.integer = kFskMediaPlayerFlagHasAudio;

	if (kFskErrNone == FskMediaMetaDataGet(state->mi.meta, "Genre", 0, &value, NULL)) {
		if (0 == FskStrCompareCaseInsensitive(value.value.str, "Audiobooks"))
			property->value.integer |= kFskMediaPlayerFlagHasAudioBook;
	}

	if (kFskErrNone == FskMediaMetaDataGet(state->mi.meta, "Album", 0, &value, NULL)) {
		if (NULL != FskStrStr(value.value.str, "Librivox"))
			property->value.integer |= kFskMediaPlayerFlagHasAudioBook;
	}

	return kFskErrNone;
}
// ------------------------------------------------------------------------
void FskAssociativeArrayElementDispose(FskAssociativeArray array, const char *name)
{
	FskAssociativeArrayNameList		list, last = NULL;

	// try to find the list of values associated with name
	list = array->arrayHead;
	while (list) {
		if (FskStrCompareCaseInsensitive(name, list->name) == 0) {
			// kill existing list
			if (last)
				last->next = list->next;
			else
				array->arrayHead = list->next;

			FskMemPtrDispose(list);

			break; // while(list)
		}
		last = list;
		list = list->next;
	}
}
Exemple #12
0
Boolean FskSSLCheckServerCert(SSL *ssl, char *hostname) {
	long err;
	X509 *peer;
	char peer_CN[256];
	err = SSL_get_verify_result(ssl);
#if 0
	if ((err != X509_V_OK)
		&& (err != X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT)
		&& (err != X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY)) {
		ERR_print_errors_fp(stderr);
fprintf(stderr, "[%s] cert for %s didn't verify %d %s\n", threadTag(FskThreadGetCurrent()), hostname, err, X509_verify_cert_error_string(err));
#else
	if (err != X509_V_OK) {
		if ((NULL != FskStrStr(hostname, "google.com")) 
			|| (NULL != FskStrStr(hostname, "googleapis.com")) 
			|| (NULL != FskStrStr(hostname, "twitter.com"))
			|| (NULL != FskStrStr(hostname, "yammer.com"))
			|| (NULL != FskStrStr(hostname, "facebook.com"))
			|| (NULL != FskStrStr(hostname, "foursquare.com"))
			|| (NULL != FskStrStr(hostname, "akamaihd.net"))
			|| (NULL != FskStrStr(hostname, "fbcdn.net"))
			|| (NULL != FskStrStr(hostname, "radiotime.com"))
			|| (NULL != FskStrStr(hostname, "s3.amazonaws.com"))
			|| (NULL != FskStrStr(hostname, "orb.com"))) {
			if ((err != X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT)
				&& (err != X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY)) {
				return false;
			}
			myprintf((stderr, "b) cert didn't verify because %d %s\n", err, X509_verify_cert_error_string(err)));
			myprintf((stderr, " but since it's %s we'll let it through\n", hostname));
		}
		else {
#endif
			return false;
		}
	}

	peer = SSL_get_peer_certificate(ssl);
	X509_NAME_get_text_by_NID(X509_get_subject_name(peer), NID_commonName,
						peer_CN, 256);
//fprintf(stderr, "comparing peer_CN %s with hostname %s\n", peer_CN, hostname);
	if (FskStrCompareCaseInsensitive(peer_CN, hostname)) {
		int pos, L, subL;
		char *match = peer_CN + 1;

		subL = FskStrLen(match);
		L = FskStrLen(hostname);
		if (peer_CN[0] == '*') {
			pos = L - subL;
			if (0 == FskStrCompareCaseInsensitive(match, hostname + pos)) {
//fprintf(stderr, "Matched wildcard %s and %s\n", match, hostname + pos);
				return true;
			}
		}

		if (	(FskStrEndsWith(match, "akamaihd.net")
				&& FskStrEndsWith(hostname, "akamai.net")) 
			||	(FskStrEndsWith(match, "akamai.net")
				&& FskStrEndsWith(hostname, "akamaihd.net")) ) {
			return true;
		}
			
	

		myprintf((stderr, "cert common name %s and host %s don't match\n", peer_CN, hostname));
		return false;
	}

	return true;
}

//SSL_CTX *FskSSLInitialize(char *keyfile, char *password)
static SSL_CTX *FskOpenSSLInitialize(const char *calistpath)
{
	SSL_METHOD	*method;
	SSL_CTX		*context;

	if (gSSLContext) {
		return gSSLContext;
	}
	else {
		SSL_library_init();
		SSL_load_error_strings();			// not necessary, but useful
	}

	method = SSLv23_method();
	context = SSL_CTX_new(method);

#if 0
	if (FskStrLen(keyfile) > 0) {
		keyfile = FskEnvironmentDoApply(FskStrDoCopy(keyfile));
		if (!SSL_CTX_use_certificate_chain_file(context, keyfile))
			doSSLError("Can't read certificate file");
		fprintf(stderr, "keyfile is %s\n", keyfile);

		if (FskStrLen(password) > 0) {
			gSSLPassword = FskStrDoCopy(password);
			SSL_CTX_set_default_passwd_cb(context, passwordCallback);
			if (!SSL_CTX_use_PrivateKey_file(context, keyfile, SSL_FILETYPE_PEM))
				doSSLError( "Can't read private keyfile");
		}

		FskMemPtrDispose(keyfile);
	}
#endif

#if TARGET_OS_WIN32
	{
	// try to make the path 8.3 safe to avoid nightmares with multibyte character paths, etc.
	UInt16 *nativePath;

	if (kFskErrNone == FskFilePathToNative(calistpath, (char **)&nativePath)) {
		DWORD shortLen;

		shortLen = GetShortPathNameW(nativePath, NULL, 0);
		if (0 != shortLen) {
			UInt16 *eightDotThree;

			if (kFskErrNone == FskMemPtrNewClear(shortLen * 2, (FskMemPtr *)&eightDotThree)) {
				if (0 != GetShortPathNameW(nativePath, eightDotThree, shortLen)) {
					char *utf8;
					UInt32 utf8Len;

					if (kFskErrNone == FskTextUnicode16LEToUTF8(eightDotThree, shortLen * 2, &utf8, &utf8Len)) {
						char *enc;

						if (kFskErrNone == FskTextToPlatform(utf8, utf8Len, &enc, NULL)) {
							FskMemPtrDispose(calistpath);
							calistpath = enc;
						}
						FskMemPtrDispose(utf8);
					}
				}
				FskMemPtrDispose(eightDotThree);
			}
		}
		FskMemPtrDispose(nativePath);
	}
	}
#endif

	if (!(SSL_CTX_load_verify_locations(context, calistpath, 0))) {
		doSSLError("Can't read default CA list");
	}

	SSL_CTX_set_verify_depth(context, 0);

//	SSL_CTX_set_verify(context, SSL_VERIFY_PEER, 0);

	gSSLContext = context;

	return context;
}
FskErr mp3SpoolerCallback(void *clientRefCon, UInt32 operation, void *param)
{
	mp3Reader state = clientRefCon;
	FskErr err = kFskErrNone;

	switch (operation) {
		case kFskMediaSpoolerOperationDataReady:
			state->spoolerPosition += (UInt32)param;
			if (state->reader->mediaState < kFskMediaPlayerStateStopped) {
				if (state->id3.data) {
					UInt32 percent, bytesRead;
					void *buffer;

					if (state->id3.size != state->id3.offset) {
						err = FskMediaSpoolerRead(state->spooler, state->id3.offset, (UInt32)(state->id3.size - state->id3.offset), &buffer, &bytesRead);
						if (kFskErrNone == err) {
							FskMemMove((char *)state->id3.data + state->id3.offset, buffer, bytesRead);
							state->id3.offset += bytesRead;
						}
					}

					percent = (UInt32)((((float)state->id3.offset) / ((float)state->id3.size)) * 100.0);
					if (percent < 100)
						(state->reader->doSetState)(state->reader, kFskMediaPlayerStateInstantiatingProgress + percent);
					else
						err = mp3Instantiate(state);
				}
				else
					err = mp3Instantiate(state);
			}
			break;

		case kFskMediaSpoolerOperationSetHeaders: {
			FskHeaders *headers = param;
			FskHeaderAddString("icy-metadata", "1", headers);

			}
			break;

		case kFskMediaSpoolerOperationGetHeaders: {
			FskHeaders *headers = param;
			char *value = FskHeaderFind("icy-metaint", headers);
			state->icy.metaInt = (NULL != value) ? FskStrToNum(value) : 0;
			state->icy.nextMetaPosition = state->icy.metaInt;

			if ((NULL == state->mi.meta) || (kFskErrNone != FskMediaMetaDataGet(state->mi.meta, "FullName", 0, NULL, NULL))) {
				value = FskHeaderFind("icy-name", headers);
				if (NULL == value)
					value = FskHeaderFind("x-audiocast-name", headers);
				state->icy.title = FskStrDoCopy(value);
			}

			state->icy.isProtocol = 0 == FskStrCompare(headers->protocol, "ICY");

			value = FskHeaderFind("Server", headers);
			if (NULL != value) {
				if (0 == FskStrCompareWithLength("Orbiter", value, 7)) {
					if (!state->isOrbiter) {
						state->isOrbiter = true;
						state->reader->needsIdle = true;
						FskTimeGetNow(&state->orbStart);
					}
				}
			}

			if (state->icy.isNanocaster) {
				value = FskHeaderFind("icy-genre", headers);
				if ((NULL != value) && (0 == FskStrCompareCaseInsensitive(value, "error")))
					(state->reader->doSetState)(state->reader, kFskMediaPlayerStateFailed);
			}

            value = FskHeaderFind("availableSeekRange.dlna.org", headers);
            if (value && (0 == FskStrCompareWithLength("1 npt=", value, 6))) {
                char *dash = FskStrChr(value + 6, '-');
                double duration;
                if (dash && (kFskErrNone == FskMediaParseNPT(dash + 1, &duration)))
                    state->dlnaDuration = duration;
            }
			}
			break;

		case kFskMediaSpoolerOperationGetURI:
			state->spoolerPosition = ((FskMediaSpoolerGetURI)param)->position;
			break;
	}

	return err;
}
Exemple #14
0
static void httpProcessRequestHeaders(FskHTTPServerRequest request) {
	char 		*str;
	FskHeaders* headers = request->requestHeaders;
	UInt32 version = FskHeaderHTTPVersion(headers);
	char* host = FskHeaderFind(kFskStrHost, headers);
	char* uri = FskHeaderURI(headers);
	char* filename = FskHeaderFilename(headers);
	
	request->state = kHTTPReadRequestBody;

	if (FskStrCompareWithLength(uri, "http://", 7) == 0) {
		// remove host from filename
		char* p = FskStrStr(filename, "://") + 3;
		p = FskStrChr(p, '/') + 1;
		FskMemMove(filename, p, FskStrLen(p) + 1);
	}
	else {
		if (host) {
			if (FskMemPtrNewClear(FskStrLen(host) + FskStrLen(uri) + 9, &str) != kFskErrNone)
				headers->responseCode = 500;
			else {
				FskStrCat(str, "http://");
				FskStrCat(str, host);
				FskStrCat(str, "/");
				FskStrCat(str, headers->URI);
				FskMemPtrDispose(headers->URI);
				headers->URI = str;
			}
		}
		else if (version >= kFskHTTPVersion1dot1)
			headers->responseCode = 400;
		else if (version == kFskHTTPVersion1dot0) {
			if (FskMemPtrNewClear(FskStrLen(uri) + 9, &str) != kFskErrNone)
				headers->responseCode = 500;
			else {
				FskStrCat(str, "http:///");
				FskStrCat(str, headers->URI);
				FskMemPtrDispose(headers->URI);
				headers->URI = str;
			}
		}
	}
	
	str = FskHeaderFind(kFskStrConnection, request->requestHeaders);
	if (str && FskStrCompareCaseInsensitiveWithLength(str, kFskStrClose, 5) == 0) 
		request->keepAlive = false;
	else
		request->keepAlive = true;

	str = FskHeaderFind(kFskStrContentLength, request->requestHeaders);
	if (str) {
		request->requestBodyContentLength = FskStrToNum(str);
		request->stats.expectedBytesToReceive = FskStrToNum(str);
	}
	else
		request->stats.expectedBytesToReceive = 0;

	str = FskHeaderFind(kFskStrTransferEncoding, request->requestHeaders);
	if (str && (FskStrCompareCaseInsensitiveWithLength(str, kFskStrChunked, FskStrLen(kFskStrChunked)) == 0))
		request->requestBodyChunked = true;
	else
		request->requestBodyChunked = false;
	
	doCallCondition(request->http->callbacks->requestCondition, request, kFskHTTPConditionRequestReceivedRequestHeaders, request->refCon);

	if (NULL != (str = FskHeaderFind(kFskStrExpect, request->requestHeaders))) {
		if (0 == FskStrCompareCaseInsensitive(kFskStr100Continue, str))
			request->state = kHTTPFulfillExpectation;
		else
			request->state = kHTTPDenyExpectation;
	}
}