Allow wildcard matches for non-https schemes of the form scheme://* and

scheme:*.
This commit is contained in:
Wesley Miaw
2020-06-12 18:24:27 -07:00
parent d789ef37ff
commit 9c95539a7e
5 changed files with 44 additions and 21 deletions

View File

@@ -6,14 +6,12 @@ CC=$(TARGET)g++
includes = $(wildcard *.h) includes = $(wildcard *.h)
OBJS := main.cpp DialServer.cpp DialDiscovery.cpp DialConformance.cpp DialClientInput.cpp OBJS := main.cpp DialServer.cpp DialDiscovery.cpp DialConformance.cpp DialClientInput.cpp
debug: dialclient_debug debug: CFLAGS += -DDEBUG
debug: dialclient
# You may not need all these libraries. This example uses a build of curl that needs crypto, ssl, cares, and zlib # You may not need all these libraries. This example uses a build of curl that needs crypto, ssl, cares, and zlib
dialclient: $(OBJS) ${includes} dialclient: $(OBJS) ${includes}
$(CC) -Wall -Werror -g $(OBJS) $(INCLUDES) $(LDFLAGS) -ldl -lpthread -lcurl -lz -lcrypto -lssl -o dialclient $(CC) -Wall -Werror -g $(OBJS) $(INCLUDES) $(LDFLAGS) -ldl -lpthread -lcurl -lz -lcrypto -lssl -o dialclient
dialclient_debug: $(OBJS) ${includes}
$(CC) -DDEBUG -Wall -Werror -g $(OBJS) $(INCLUDES) $(LDFLAGS) -ldl -lpthread -lcurl -lz -lcrypto -lssl -lcares -o dialclient_debug
clean: clean:
rm -f *.o dialclient rm -f *.o dialclient

View File

@@ -502,8 +502,8 @@ static void handle_dial_data(struct mg_connection *conn,
* it will not include invalid characters or a non-numeric port number. * it will not include invalid characters or a non-numeric port number.
* *
* @param origin the origin header value, which must begin with https:// * @param origin the origin header value, which must begin with https://
* @param candidate the accepted origin whitelist value, which must begin * @param candidate the authorized origin value, which must begin with
* with https:// * https://
* @return true if accepted and false if not. * @return true if accepted and false if not.
*/ */
static int host_matches(const char *origin, const char *candidate) { static int host_matches(const char *origin, const char *candidate) {
@@ -596,13 +596,40 @@ static int host_matches(const char *origin, const char *candidate) {
strncmp(origin_host, host, origin_len) == 0); strncmp(origin_host, host, origin_len) == 0);
} }
/**
* Returns true if the origin is acceptable based on the candidate value.
* The origin must be an exact match to the candidate, unless the
* candidate is of the form 'scheme://*' or 'scheme:*' in which case
* everything before the wildcard '*' character must be an exact match but
* anything is accepted in place of the wildcard.
*
* This function assumes that the candidate value is well-formed, meaning
* it will not include invalid chracters and it will be a valid URI.
*
* @param origin the origin header value.
* @param candidate the authorized origin value.
* @return true if accepted and false if not.
*/
static int origin_matches(const char *origin, const char *candidate) { static int origin_matches(const char *origin, const char *candidate) {
// Make sure there is something to compare. // Make sure there is something to compare.
if (!origin || !candidate) if (!origin || !candidate)
return 0; return 0;
// Require an exact match. // If the candidate consists of a scheme followed by wildcard,
// require an exact match of the scheme specifier.
size_t origin_len = strlen(origin); size_t origin_len = strlen(origin);
size_t candidate_len = strlen(candidate);
if (candidate_len > 1 && candidate[candidate_len - 1] == '*') {
// The origin must be at least as long as the candidate for a
// wildcard match to succeed.
if (origin_len < candidate_len)
return 0;
fprintf(stderr, "comparing %s to %s len %lld\n", origin, candidate, candidate_len);
return strncmp(origin, candidate, candidate_len - 1) == 0;
}
// Require an exact match.
return (origin_len == strlen(candidate) && return (origin_len == strlen(candidate) &&
strncmp(origin, candidate, origin_len) == 0); strncmp(origin, candidate, origin_len) == 0);
} }
@@ -639,8 +666,8 @@ static int is_uri_in_list(const char *origin, const char *list) {
candidate[copyLength] = '\0'; candidate[copyLength] = '\0';
//printf("found %s \n", candidate); //printf("found %s \n", candidate);
// If the URI begins with https://, perform a host comparison because // If the URI begins with https://, perform a host comparison because
// any port numbers must be handled specially. Otherwise require an // any port numbers must be handled specially. Otherwise perform a
// exact match. // regular match.
if ((isHttps && host_matches(origin, candidate)) || if ((isHttps && host_matches(origin, candidate)) ||
(!isHttps && origin_matches(origin, candidate))) (!isHttps && origin_matches(origin, candidate)))
{ {

View File

@@ -289,11 +289,11 @@ void runDial(void)
struct DIALAppCallbacks cb_system = {system_start, system_hide, NULL, system_status}; struct DIALAppCallbacks cb_system = {system_start, system_hide, NULL, system_status};
#if defined DEBUG #if defined DEBUG
if (DIAL_register_app(ds, "Netflix", &cb_nf, NULL, 1, "https://netflix.com https://www.netflix.com https://port.netflix.com:123") == -1 || if (DIAL_register_app(ds, "Netflix", &cb_nf, NULL, 1, "https://netflix.com https://www.netflix.com https://port.netflix.com:123 proto://*") == -1 ||
DIAL_register_app(ds, "YouTube", &cb_yt, NULL, 1, "https://youtube.com https://www.youtube.com https://*.youtube.com:443 https://port.youtube.com:123 package:com.google.android.youtube package:com.google.ios.youtube") == -1 || DIAL_register_app(ds, "YouTube", &cb_yt, NULL, 1, "https://youtube.com https://www.youtube.com https://*.youtube.com:443 https://port.youtube.com:123 package:com.google.android.youtube package:com.google.ios.youtube proto:*") == -1 ||
#else #else
if (DIAL_register_app(ds, "Netflix", &cb_nf, NULL, 1, "https://netflix.com https://www.netflix.com") == -1 || if (DIAL_register_app(ds, "Netflix", &cb_nf, NULL, 1, "https://netflix.com https://www.netflix.com") == -1 ||
DIAL_register_app(ds, "YouTube", &cb_yt, NULL, 1, "https://youtube.com https://*.youtube.com package:com.google.android.youtube package:com.google.ios.youtube") == -1 || DIAL_register_app(ds, "YouTube", &cb_yt, NULL, 1, "https://youtube.com https://*.youtube.com package:*") == -1 ||
#endif #endif
DIAL_register_app(ds, "system", &cb_system, NULL, 1, "") == -1) DIAL_register_app(ds, "system", &cb_system, NULL, 1, "") == -1)
{ {

View File

@@ -13,7 +13,8 @@ HEADERS := $(wildcard *.h)
$(CC) -Wall -g -fPIC -std=gnu99 $(CFLAGS) -c $*.c -o $*.o $(CC) -Wall -g -fPIC -std=gnu99 $(CFLAGS) -c $*.c -o $*.o
all: dialserver all: dialserver
debug: dialserver_debug test debug: CFLAGS += -DDEBUG
debug: dialserver test
nf_callbacks_lib: nf_callbacks.o nf_callbacks_lib: nf_callbacks.o
# $(CC) -Wall -Werror -g nf_callbacks.o -o libnfCallbacks.so --shared # $(CC) -Wall -Werror -g nf_callbacks.o -o libnfCallbacks.so --shared
@@ -22,9 +23,6 @@ nf_callbacks_lib: nf_callbacks.o
dialserver: nf_callbacks_lib $(OBJS) dialserver: nf_callbacks_lib $(OBJS)
$(CC) -Wall -Werror -Wl,-rpath,. -g $(OBJS) -ldl -lpthread -lrt -L. -lnfCallbacks -o dialserver $(CC) -Wall -Werror -Wl,-rpath,. -g $(OBJS) -ldl -lpthread -lrt -L. -lnfCallbacks -o dialserver
dialserver_debug: nf_callbacks_lib $(OBJS)
$(CC) -DDEBUG -Wall -Werror -Wl,-rpath,. -g $(OBJS) -ldl -lpthread -lrt -L. -lnfCallbacks -o dialserver
dialserver_with_ASAN: nf_callbacks_lib $(OBJS) dialserver_with_ASAN: nf_callbacks_lib $(OBJS)
$(CC) -Wall -Werror -fsanitize=address -Wl,-rpath,. -g $(OBJS) -ldl -lpthread -lrt -L. -lnfCallbacks -o dialserver_with_ASAN $(CC) -Wall -Werror -fsanitize=address -Wl,-rpath,. -g $(OBJS) -ldl -lpthread -lrt -L. -lnfCallbacks -o dialserver_with_ASAN

View File

@@ -9,7 +9,7 @@ ip_address=$1
port=$2 port=$2
#Testing all the positive cases #Testing all the positive cases
origins="https://www.netflix.com https://netflix.com https://port.netflix.com:123 https://www.netflix.com:80 https://www.netflix.com:123" origins="https://www.netflix.com https://netflix.com https://port.netflix.com:123 https://www.netflix.com:80 https://www.netflix.com:123 proto://netflix.com proto://netflix proto://netflix.com:123"
for origin in $origins; do for origin in $origins; do
curl --fail --silent --header "Origin:$origin" --data "v=QH2-TGUlwu4" http://$ip_address:$port/apps/Netflix || echo "failed: $origin should be accepted" curl --fail --silent --header "Origin:$origin" --data "v=QH2-TGUlwu4" http://$ip_address:$port/apps/Netflix || echo "failed: $origin should be accepted"
curl --fail --silent --header "Origin:$origin" -X OPTIONS http://$ip_address:$port/apps/Netflix || echo "failed: $origin should be accepted" curl --fail --silent --header "Origin:$origin" -X OPTIONS http://$ip_address:$port/apps/Netflix || echo "failed: $origin should be accepted"
@@ -21,7 +21,7 @@ then
fi fi
done done
origins="https://www.youtube.com https://music.youtube.com https://youtube.com https://port.youtube.com:123 https://www.youtube.com:80 https://www.youtube.com:123 package:com.google.android.youtube package:com.google.ios.youtube" origins="https://www.youtube.com https://music.youtube.com https://youtube.com https://port.youtube.com:123 https://www.youtube.com:80 https://www.youtube.com:123 package:com.google.android.youtube package:com.google.ios.youtube proto:g proto:com.google"
for origin in $origins; do for origin in $origins; do
curl --fail --silent --header "Origin:$origin" --data "v=QH2-TGUlwu4" http://$ip_address:$port/apps/YouTube || echo "failed: $origin should be accepted" curl --fail --silent --header "Origin:$origin" --data "v=QH2-TGUlwu4" http://$ip_address:$port/apps/YouTube || echo "failed: $origin should be accepted"
curl --fail --silent --header "Origin:$origin" -X OPTIONS http://$ip_address:$port/apps/YouTube || echo "failed: $origin should be accepted" curl --fail --silent --header "Origin:$origin" -X OPTIONS http://$ip_address:$port/apps/YouTube || echo "failed: $origin should be accepted"
@@ -34,7 +34,7 @@ fi
done done
#Testing all the negative cases #Testing all the negative cases
origins="http://www.netflix-a.com http://www.netflix.com4 http://a-netflix.com http://www4.netflix.com https://port.netflix.com:1234 http://1.netflix.com https://www4.netflix.com https://ww.netflix-a.com https://www.netflix.com4 https://a-netflix.com http://netflix.com http://www.attack.com https://www.attack.com file://www.attack.com ftp://this.is.not.fine package: package:com.netflix.null" origins="http://www.netflix-a.com http://www.netflix.com4 http://a-netflix.com http://www4.netflix.com https://port.netflix.com:1234 http://1.netflix.com https://www4.netflix.com https://ww.netflix-a.com https://www.netflix.com4 https://a-netflix.com http://netflix.com http://www.attack.com https://www.attack.com file://www.attack.com ftp://this.is.not.fine package: package:com.netflix.null proto:// proto:n proto:/n proto"
for origin in $origins; do for origin in $origins; do
curl --fail --silent --header "Origin:$origin" --data "v=QH2-TGUlwu4" http://$ip_address:$port/apps/Netflix && echo "failed: $origin should be rejected" curl --fail --silent --header "Origin:$origin" --data "v=QH2-TGUlwu4" http://$ip_address:$port/apps/Netflix && echo "failed: $origin should be rejected"
curl --fail --silent --header "Origin:$origin" -X OPTIONS http://$ip_address:$port/apps/Netflix && echo "failed: $origin should be rejected" curl --fail --silent --header "Origin:$origin" -X OPTIONS http://$ip_address:$port/apps/Netflix && echo "failed: $origin should be rejected"
@@ -46,7 +46,7 @@ then
fi fi
done done
origins="http://www.youtube-a.com http://www.youtube.com4 https://.youtube.com http://a-youtube.com https://ww.youtube-a.com http://www4.youtube.com https://port.youtube.com:1234 http://1.youtube.com https://www.youtube.com4 https://a-youtube.com http://youtube.com http://www.attack.com https://www.attack.com file://www.attack.com ftp://this.is.not.fine packagecom.google.android.youtube package:com.google.android.utube" origins="http://www.youtube-a.com http://www.youtube.com4 https://.youtube.com http://a-youtube.com https://ww.youtube-a.com http://www4.youtube.com https://port.youtube.com:1234 http://1.youtube.com https://www.youtube.com4 https://a-youtube.com http://youtube.com http://www.attack.com https://www.attack.com file://www.attack.com ftp://this.is.not.fine packagecom.google.android.youtube package:com.google.android.utube packagea package: pack:com.google.android protoa proto:"
for origin in $origins; do for origin in $origins; do
curl --fail --silent --header "Origin:$origin" --data "v=QH2-TGUlwu4" http://$ip_address:$port/apps/YouTube && echo "failed: $origin should be rejected" curl --fail --silent --header "Origin:$origin" --data "v=QH2-TGUlwu4" http://$ip_address:$port/apps/YouTube && echo "failed: $origin should be rejected"
curl --fail --silent --header "Origin:$origin" -X OPTIONS http://$ip_address:$port/apps/YouTube && echo "failed: $origin should be rejected" curl --fail --silent --header "Origin:$origin" -X OPTIONS http://$ip_address:$port/apps/YouTube && echo "failed: $origin should be rejected"