1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3 * Copyright (C) 2018 Igalia S.L.
4 * Copyright (C) 2018 Metrological Group B.V.
5 */
6
7 #include "test-utils.h"
8
9 SoupURI *http_uri;
10 SoupURI *https_uri;
11
12 /* This server pseudo-implements the HSTS spec in order to allow us to
13 test the Soup HSTS feature.
14 */
15 static void
server_callback(SoupServer * server,SoupMessage * msg,const char * path,GHashTable * query,SoupClientContext * context,gpointer data)16 server_callback (SoupServer *server, SoupMessage *msg,
17 const char *path, GHashTable *query,
18 SoupClientContext *context, gpointer data)
19 {
20 const char *server_protocol = data;
21
22 if (strcmp (server_protocol, "http") == 0) {
23 if (strcmp (path, "/insecure") == 0) {
24 soup_message_headers_append (msg->response_headers,
25 "Strict-Transport-Security",
26 "max-age=31536000");
27 soup_message_set_status (msg, SOUP_STATUS_OK);
28 } else {
29 char *uri_string;
30 SoupURI *uri = soup_uri_new ("https://localhost");
31 soup_uri_set_path (uri, path);
32 uri_string = soup_uri_to_string (uri, FALSE);
33 soup_message_set_redirect (msg, SOUP_STATUS_MOVED_PERMANENTLY, uri_string);
34 soup_uri_free (uri);
35 g_free (uri_string);
36 }
37 } else if (strcmp (server_protocol, "https") == 0) {
38 soup_message_set_status (msg, SOUP_STATUS_OK);
39 if (strcmp (path, "/long-lasting") == 0) {
40 soup_message_headers_append (msg->response_headers,
41 "Strict-Transport-Security",
42 "max-age=31536000");
43 } else if (strcmp (path, "/two-seconds") == 0) {
44 soup_message_headers_append (msg->response_headers,
45 "Strict-Transport-Security",
46 "max-age=2");
47 } else if (strcmp (path, "/three-seconds") == 0) {
48 soup_message_headers_append (msg->response_headers,
49 "Strict-Transport-Security",
50 "max-age=3");
51 } else if (strcmp (path, "/delete") == 0) {
52 soup_message_headers_append (msg->response_headers,
53 "Strict-Transport-Security",
54 "max-age=0");
55 } else if (strcmp (path, "/subdomains") == 0) {
56 soup_message_headers_append (msg->response_headers,
57 "Strict-Transport-Security",
58 "max-age=31536000; includeSubDomains");
59 } else if (strcmp (path, "/no-sts-header") == 0) {
60 /* Do not add anything */
61 } else if (strcmp (path, "/multiple-headers") == 0) {
62 soup_message_headers_append (msg->response_headers,
63 "Strict-Transport-Security",
64 "max-age=31536000; includeSubDomains");
65 soup_message_headers_append (msg->response_headers,
66 "Strict-Transport-Security",
67 "max-age=1; includeSubDomains");
68 } else if (strcmp (path, "/missing-values") == 0) {
69 soup_message_headers_append (msg->response_headers,
70 "Strict-Transport-Security",
71 "");
72 } else if (strcmp (path, "/invalid-values") == 0) {
73 soup_message_headers_append (msg->response_headers,
74 "Strict-Transport-Security",
75 "max-age=foo");
76 } else if (strcmp (path, "/extra-values-0") == 0) {
77 soup_message_headers_append (msg->response_headers,
78 "Strict-Transport-Security",
79 "max-age=3600; foo");
80 } else if (strcmp (path, "/extra-values-1") == 0) {
81 soup_message_headers_append (msg->response_headers,
82 "Strict-Transport-Security",
83 " max-age=3600; includeDomains; foo");
84 } else if (strcmp (path, "/duplicated-directives") == 0) {
85 soup_message_headers_append (msg->response_headers,
86 "Strict-Transport-Security",
87 "max-age=3600; includeDomains; includeDomains");
88 } else if (strcmp (path, "/case-insensitive-header") == 0) {
89 soup_message_headers_append (msg->response_headers,
90 "STRICT-TRANSPORT-SECURITY",
91 "max-age=3600");
92 } else if (strcmp (path, "/case-insensitive-directives") == 0) {
93 soup_message_headers_append (msg->response_headers,
94 "Strict-Transport-Security",
95 "MAX-AGE=3600; includesubdomains");
96 } else if (strcmp (path, "/optional-quotations") == 0) {
97 soup_message_headers_append (msg->response_headers,
98 "Strict-Transport-Security",
99 "max-age=\"31536000\"");
100 }
101 }
102 }
103
104 static void
session_get_uri(SoupSession * session,const char * uri,SoupStatus expected_status)105 session_get_uri (SoupSession *session, const char *uri, SoupStatus expected_status)
106 {
107 SoupMessage *msg;
108
109 msg = soup_message_new ("GET", uri);
110 soup_message_set_flags (msg, SOUP_MESSAGE_NO_REDIRECT);
111 soup_session_send_message (session, msg);
112 soup_test_assert_message_status (msg, expected_status);
113 g_object_unref (msg);
114 }
115
116 /* The HSTS specification does not handle custom ports, so we need to
117 * rewrite the URI in the request and add the port where the server is
118 * listening before it is sent, to be able to connect to the localhost
119 * port where the server is actually running.
120 */
121 static void
rewrite_message_uri(SoupMessage * msg)122 rewrite_message_uri (SoupMessage *msg)
123 {
124 if (soup_uri_get_scheme (soup_message_get_uri (msg)) == SOUP_URI_SCHEME_HTTP)
125 soup_uri_set_port (soup_message_get_uri (msg), soup_uri_get_port (http_uri));
126 else if (soup_uri_get_scheme (soup_message_get_uri (msg)) == SOUP_URI_SCHEME_HTTPS)
127 soup_uri_set_port (soup_message_get_uri (msg), soup_uri_get_port (https_uri));
128 else
129 g_assert_not_reached();
130 }
131
132 static void
on_message_restarted(SoupMessage * msg,gpointer data)133 on_message_restarted (SoupMessage *msg,
134 gpointer data)
135 {
136 rewrite_message_uri (msg);
137 }
138
139 static void
on_request_queued(SoupSession * session,SoupMessage * msg,gpointer data)140 on_request_queued (SoupSession *session,
141 SoupMessage *msg,
142 gpointer data)
143 {
144 g_signal_connect (msg, "restarted", G_CALLBACK (on_message_restarted), NULL);
145
146 rewrite_message_uri (msg);
147 }
148
149 static SoupSession *
hsts_session_new(SoupHSTSEnforcer * enforcer)150 hsts_session_new (SoupHSTSEnforcer *enforcer)
151 {
152 SoupSession *session;
153
154 if (enforcer)
155 session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC,
156 SOUP_SESSION_USE_THREAD_CONTEXT, TRUE,
157 SOUP_SESSION_ADD_FEATURE, enforcer,
158 NULL);
159 else
160 session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC,
161 SOUP_SESSION_USE_THREAD_CONTEXT, TRUE,
162 SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_HSTS_ENFORCER,
163 NULL);
164
165 g_signal_connect (session, "request-queued", G_CALLBACK (on_request_queued), NULL);
166
167 return session;
168 }
169
170
171 static void
do_hsts_basic_test(void)172 do_hsts_basic_test (void)
173 {
174 SoupSession *session = hsts_session_new (NULL);
175
176 session_get_uri (session, "http://localhost", SOUP_STATUS_MOVED_PERMANENTLY);
177 session_get_uri (session, "https://localhost/long-lasting", SOUP_STATUS_OK);
178 session_get_uri (session, "http://localhost", SOUP_STATUS_OK);
179
180 /* The HSTS headers in the url above doesn't include
181 subdomains, so the request should ask for the unchanged
182 HTTP address below, to which the server will respond with a
183 moved permanently status. */
184 session_get_uri (session, "http://subdomain.localhost", SOUP_STATUS_MOVED_PERMANENTLY);
185
186 soup_test_session_abort_unref (session);
187 }
188
189 static void
do_hsts_expire_test(void)190 do_hsts_expire_test (void)
191 {
192 SoupSession *session = hsts_session_new (NULL);
193
194 session_get_uri (session, "https://localhost/two-seconds", SOUP_STATUS_OK);
195 session_get_uri (session, "http://localhost", SOUP_STATUS_OK);
196 /* Wait for the policy to expire. */
197 g_usleep (3 * G_USEC_PER_SEC);
198 session_get_uri (session, "http://localhost", SOUP_STATUS_MOVED_PERMANENTLY);
199
200 soup_test_session_abort_unref (session);
201 }
202
203 static void
do_hsts_delete_test(void)204 do_hsts_delete_test (void)
205 {
206 SoupSession *session = hsts_session_new (NULL);
207
208 session_get_uri (session, "http://localhost", SOUP_STATUS_MOVED_PERMANENTLY);
209 session_get_uri (session, "https://localhost/delete", SOUP_STATUS_OK);
210 session_get_uri (session, "http://localhost", SOUP_STATUS_MOVED_PERMANENTLY);
211
212 soup_test_session_abort_unref (session);
213 }
214
215 static void
do_hsts_replace_test(void)216 do_hsts_replace_test (void)
217 {
218 SoupSession *session = hsts_session_new (NULL);
219 session_get_uri (session, "https://localhost/long-lasting", SOUP_STATUS_OK);
220 session_get_uri (session, "http://localhost", SOUP_STATUS_OK);
221 session_get_uri (session, "https://localhost/two-seconds", SOUP_STATUS_OK);
222 /* Wait for the policy to expire. */
223 g_usleep (3 * G_USEC_PER_SEC);
224 session_get_uri (session, "http://localhost", SOUP_STATUS_MOVED_PERMANENTLY);
225
226 soup_test_session_abort_unref (session);
227 }
228
229 static void
do_hsts_update_test(void)230 do_hsts_update_test (void)
231 {
232 SoupSession *session = hsts_session_new (NULL);
233 session_get_uri (session, "https://localhost/three-seconds", SOUP_STATUS_OK);
234 g_usleep (2 * G_USEC_PER_SEC);
235 session_get_uri (session, "https://localhost/three-seconds", SOUP_STATUS_OK);
236 g_usleep (2 * G_USEC_PER_SEC);
237
238 /* At this point, 4 seconds have elapsed since setting the 3 seconds HSTS
239 rule for the first time, and it should have expired by now, but since it
240 was updated, it should still be valid. */
241 session_get_uri (session, "http://localhost", SOUP_STATUS_OK);
242 soup_test_session_abort_unref (session);
243 }
244
245 static void
do_hsts_set_and_delete_test(void)246 do_hsts_set_and_delete_test (void)
247 {
248 SoupSession *session = hsts_session_new (NULL);
249 session_get_uri (session, "https://localhost/long-lasting", SOUP_STATUS_OK);
250 session_get_uri (session, "http://localhost", SOUP_STATUS_OK);
251 session_get_uri (session, "https://localhost/delete", SOUP_STATUS_OK);
252 session_get_uri (session, "http://localhost", SOUP_STATUS_MOVED_PERMANENTLY);
253
254 soup_test_session_abort_unref (session);
255 }
256
257 static void
do_hsts_no_hsts_header_test(void)258 do_hsts_no_hsts_header_test (void)
259 {
260 SoupSession *session = hsts_session_new (NULL);
261 session_get_uri (session, "https://localhost/long-lasting", SOUP_STATUS_OK);
262 session_get_uri (session, "http://localhost", SOUP_STATUS_OK);
263 session_get_uri (session, "https://localhost/no-sts-header", SOUP_STATUS_OK);
264 session_get_uri (session, "http://localhost", SOUP_STATUS_OK);
265
266 soup_test_session_abort_unref (session);
267 }
268
269 static void
do_hsts_persistency_test(void)270 do_hsts_persistency_test (void)
271 {
272 SoupSession *session = hsts_session_new (NULL);
273 session_get_uri (session, "https://localhost/long-lasting", SOUP_STATUS_OK);
274 session_get_uri (session, "http://localhost", SOUP_STATUS_OK);
275 soup_test_session_abort_unref (session);
276
277 session = hsts_session_new (NULL);
278 session_get_uri (session, "http://localhost", SOUP_STATUS_MOVED_PERMANENTLY);
279 soup_test_session_abort_unref (session);
280 }
281
282 static void
do_hsts_subdomains_test(void)283 do_hsts_subdomains_test (void)
284 {
285 SoupSession *session = hsts_session_new (NULL);
286 session_get_uri (session, "https://localhost/subdomains", SOUP_STATUS_OK);
287 /* The enforcer should cause the request to ask for an HTTPS
288 uri, which will fail with an SSL error as there's no server
289 in subdomain.localhost. */
290 session_get_uri (session, "http://subdomain.localhost", SOUP_STATUS_SSL_FAILED);
291 soup_test_session_abort_unref (session);
292 }
293
294 static void
do_hsts_superdomain_test(void)295 do_hsts_superdomain_test (void)
296 {
297 SoupHSTSEnforcer *enforcer = soup_hsts_enforcer_new ();
298 SoupHSTSPolicy *policy;
299
300 SoupSession *session = hsts_session_new (enforcer);
301 /* This adds a long-lasting policy for localhost. */
302 session_get_uri (session, "https://localhost/long-lasting", SOUP_STATUS_OK);
303
304 /* We want to set a policy with age = 0 for a subdomain, to test that the
305 superdomain's policy is not removed. We cannot test this with a
306 server, so we just create one by hand and add it to the enforcer. */
307 policy = soup_hsts_policy_new ("subdomain.localhost", 0, TRUE);
308 soup_hsts_enforcer_set_policy (enforcer, policy);
309 soup_hsts_policy_free (policy);
310
311 /* This should work, as we have a long-lasting policy in place. If it fails,
312 the subdomain policy has modified the superdomain's policy, which is wrong. */
313 session_get_uri (session, "http://localhost", SOUP_STATUS_OK);
314 g_object_unref (enforcer);
315 }
316
317 static void
do_hsts_multiple_headers_test(void)318 do_hsts_multiple_headers_test (void)
319 {
320 SoupSession *session = hsts_session_new (NULL);
321 session_get_uri (session, "https://localhost/multiple-headers", SOUP_STATUS_OK);
322 g_usleep(2 * G_USEC_PER_SEC);
323 session_get_uri (session, "http://localhost", SOUP_STATUS_OK);
324 soup_test_session_abort_unref (session);
325 }
326
327 static void
do_hsts_insecure_sts_test(void)328 do_hsts_insecure_sts_test (void)
329 {
330 SoupSession *session = hsts_session_new (NULL);
331 session_get_uri (session, "http://localhost/insecure", SOUP_STATUS_OK);
332 session_get_uri (session, "http://localhost", SOUP_STATUS_MOVED_PERMANENTLY);
333 soup_test_session_abort_unref (session);
334 }
335
336 static void
do_hsts_missing_values_test(void)337 do_hsts_missing_values_test (void)
338 {
339 SoupSession *session = hsts_session_new (NULL);
340 session_get_uri (session, "https://localhost/missing-values", SOUP_STATUS_OK);
341 session_get_uri (session, "http://localhost", SOUP_STATUS_MOVED_PERMANENTLY);
342 soup_test_session_abort_unref (session);
343 }
344
345 static void
do_hsts_invalid_values_test(void)346 do_hsts_invalid_values_test (void)
347 {
348 SoupSession *session = hsts_session_new (NULL);
349 session_get_uri (session, "https://localhost/invalid-values", SOUP_STATUS_OK);
350 session_get_uri (session, "http://localhost", SOUP_STATUS_MOVED_PERMANENTLY);
351 soup_test_session_abort_unref (session);
352 }
353
354 static void
do_hsts_extra_values_test(void)355 do_hsts_extra_values_test (void)
356 {
357 int i;
358 for (i = 0; i < 2; i++) {
359 SoupSession *session = hsts_session_new (NULL);
360 char *uri = g_strdup_printf ("https://localhost/extra-values-%i", i);
361 session_get_uri (session, uri, SOUP_STATUS_OK);
362 session_get_uri (session, "http://localhost", SOUP_STATUS_OK);
363 soup_test_session_abort_unref (session);
364 g_free (uri);
365 }
366 }
367
368 static void
do_hsts_duplicated_directives_test(void)369 do_hsts_duplicated_directives_test (void)
370 {
371 SoupSession *session = hsts_session_new (NULL);
372 session_get_uri (session, "https://localhost/duplicated-directives", SOUP_STATUS_OK);
373 session_get_uri (session, "http://localhost", SOUP_STATUS_MOVED_PERMANENTLY);
374 soup_test_session_abort_unref (session);
375 }
376
377 static void
do_hsts_case_insensitive_header_test(void)378 do_hsts_case_insensitive_header_test (void)
379 {
380 SoupSession *session = hsts_session_new (NULL);
381 session_get_uri (session, "https://localhost/case-insensitive-header", SOUP_STATUS_OK);
382 session_get_uri (session, "http://localhost", SOUP_STATUS_OK);
383 soup_test_session_abort_unref (session);
384 }
385
386 static void
do_hsts_case_insensitive_directives_test(void)387 do_hsts_case_insensitive_directives_test (void)
388 {
389 SoupSession *session = hsts_session_new (NULL);
390 session_get_uri (session, "https://localhost/case-insensitive-directives", SOUP_STATUS_OK);
391 session_get_uri (session, "http://localhost", SOUP_STATUS_OK);
392 soup_test_session_abort_unref (session);
393 }
394
395 static void
do_hsts_optional_quotations_test(void)396 do_hsts_optional_quotations_test (void)
397 {
398 SoupSession *session = hsts_session_new (NULL);
399
400 session_get_uri (session, "https://localhost/optional-quotations", SOUP_STATUS_OK);
401 session_get_uri (session, "http://localhost", SOUP_STATUS_OK);
402
403 soup_test_session_abort_unref (session);
404 }
405
406 static void
do_hsts_ip_address_test(void)407 do_hsts_ip_address_test (void)
408 {
409 SoupSession *session = hsts_session_new (NULL);
410 session_get_uri (session, "https://127.0.0.1/basic", SOUP_STATUS_OK);
411 session_get_uri (session, "http://127.0.0.1/", SOUP_STATUS_MOVED_PERMANENTLY);
412 soup_test_session_abort_unref (session);
413 }
414
415 static void
do_hsts_utf8_address_test(void)416 do_hsts_utf8_address_test (void)
417 {
418 SoupSession *session = hsts_session_new (NULL);
419 session_get_uri (session, "https://localhost/subdomains", SOUP_STATUS_OK);
420 /* The enforcer should cause the request to ask for an HTTPS
421 uri, which will fail with an SSL error as there's no server
422 in 食狮.中国.localhost. */
423 session_get_uri (session, "http://食狮.中国.localhost", SOUP_STATUS_SSL_FAILED);
424 soup_test_session_abort_unref (session);
425 }
426
427 static void
do_hsts_session_policy_test(void)428 do_hsts_session_policy_test (void)
429 {
430 SoupHSTSEnforcer *enforcer = soup_hsts_enforcer_new ();
431 SoupSession *session = hsts_session_new (enforcer);
432
433 session_get_uri (session, "http://localhost", SOUP_STATUS_MOVED_PERMANENTLY);
434 soup_hsts_enforcer_set_session_policy (enforcer, "localhost", FALSE);
435 session_get_uri (session, "http://localhost", SOUP_STATUS_OK);
436
437 soup_test_session_abort_unref (session);
438 g_object_unref (enforcer);
439 }
440
441 static void
on_idna_test_enforcer_changed(SoupHSTSEnforcer * enforcer,SoupHSTSPolicy * old,SoupHSTSPolicy * new,gpointer data)442 on_idna_test_enforcer_changed (SoupHSTSEnforcer *enforcer, SoupHSTSPolicy *old, SoupHSTSPolicy *new, gpointer data)
443 {
444 /* If NULL, then instead of replacing we're adding a new
445 * policy and somewhere we're failing to canonicalize a hostname. */
446 g_assert_nonnull (old);
447 g_assert_cmpstr (old->domain, ==, new->domain);
448 /* Domains should not have punycoded segments at this point. */
449 g_assert_false (g_hostname_is_ascii_encoded (old->domain));
450 }
451
452 static void
do_hsts_idna_addresses_test(void)453 do_hsts_idna_addresses_test (void)
454 {
455 SoupHSTSEnforcer *enforcer = soup_hsts_enforcer_new ();
456
457 soup_hsts_enforcer_set_session_policy (enforcer, "áéí.com", FALSE);
458 soup_hsts_enforcer_set_session_policy (enforcer, "xn--6scagyk0fc4c.in", FALSE);
459
460 g_assert_true (soup_hsts_enforcer_has_valid_policy (enforcer, "xn--1caqm.com"));
461
462 g_signal_connect (enforcer, "changed", G_CALLBACK (on_idna_test_enforcer_changed), NULL);
463
464 soup_hsts_enforcer_set_session_policy (enforcer, "xn--1caqm.com", TRUE);
465 soup_hsts_enforcer_set_session_policy (enforcer, "ನೆನಪಿರಲಿ.in", TRUE);
466
467 g_object_unref (enforcer);
468 }
469
470 static void
do_hsts_get_domains_test(void)471 do_hsts_get_domains_test (void)
472 {
473 SoupHSTSEnforcer *enforcer = soup_hsts_enforcer_new ();
474 SoupHSTSPolicy *policy;
475 GList* domains;
476
477 g_assert_null (soup_hsts_enforcer_get_domains (enforcer, TRUE));
478 g_assert_null (soup_hsts_enforcer_get_domains (enforcer, FALSE));
479
480 policy = soup_hsts_policy_new ("gnome.org", 3600, FALSE);
481 g_assert_nonnull (policy);
482 soup_hsts_enforcer_set_policy (enforcer, policy);
483 soup_hsts_policy_free (policy);
484
485 policy = soup_hsts_policy_new_session_policy ("freedesktop.org", FALSE);
486 g_assert_nonnull (policy);
487 soup_hsts_enforcer_set_policy (enforcer, policy);
488 soup_hsts_policy_free (policy);
489
490 domains = soup_hsts_enforcer_get_domains (enforcer, TRUE);
491 g_assert_nonnull (domains);
492 g_assert_cmpint (g_list_length (domains), ==, 2);
493 g_list_free_full (domains, (GDestroyNotify)g_free);
494
495 domains = soup_hsts_enforcer_get_domains (enforcer, FALSE);
496 g_assert_nonnull (domains);
497 g_assert_cmpint (g_list_length (domains), ==, 1);
498 g_assert_cmpstr ((char*)domains->data, ==, "gnome.org");
499 g_list_free_full (domains, (GDestroyNotify)g_free);
500
501 policy = soup_hsts_policy_new ("gnome.org", SOUP_HSTS_POLICY_MAX_AGE_PAST, FALSE);
502 soup_hsts_enforcer_set_policy (enforcer, policy);
503 soup_hsts_policy_free (policy);
504
505 domains = soup_hsts_enforcer_get_domains (enforcer, TRUE);
506 g_assert_cmpint (g_list_length (domains), ==, 1);
507 g_assert_cmpstr ((char*)domains->data, ==, "freedesktop.org");
508 g_list_free_full (domains, g_free);
509 g_object_unref (enforcer);
510 }
511
512 static void
do_hsts_get_policies_test(void)513 do_hsts_get_policies_test (void)
514 {
515 SoupHSTSEnforcer *enforcer = soup_hsts_enforcer_new ();
516 SoupHSTSPolicy *policy;
517 GList* policies;
518
519 g_assert_null (soup_hsts_enforcer_get_policies (enforcer, TRUE));
520 g_assert_null (soup_hsts_enforcer_get_policies (enforcer, FALSE));
521
522 policy = soup_hsts_policy_new ("gnome.org", 3600, FALSE);
523 g_assert_nonnull (policy);
524 soup_hsts_enforcer_set_policy (enforcer, policy);
525 soup_hsts_policy_free (policy);
526
527 policy = soup_hsts_policy_new_session_policy ("freedesktop.org", FALSE);
528 g_assert_nonnull (policy);
529 soup_hsts_enforcer_set_policy (enforcer, policy);
530 soup_hsts_policy_free (policy);
531
532 policies = soup_hsts_enforcer_get_policies (enforcer, TRUE);
533 g_assert_nonnull (policies);
534 g_assert_cmpint (g_list_length (policies), ==, 2);
535 g_list_free_full (policies, (GDestroyNotify)soup_hsts_policy_free);
536
537 policies = soup_hsts_enforcer_get_policies (enforcer, FALSE);
538 g_assert_nonnull (policies);
539 g_assert_cmpint (g_list_length (policies), ==, 1);
540 policy = (SoupHSTSPolicy*)policies->data;
541 g_assert_cmpstr (policy->domain, ==, "gnome.org");
542 g_list_free_full (policies, (GDestroyNotify)soup_hsts_policy_free);
543
544 policy = soup_hsts_policy_new ("gnome.org", SOUP_HSTS_POLICY_MAX_AGE_PAST, FALSE);
545 soup_hsts_enforcer_set_policy (enforcer, policy);
546 soup_hsts_policy_free (policy);
547
548 policies = soup_hsts_enforcer_get_policies (enforcer, TRUE);
549 g_assert_cmpint (g_list_length (policies), ==, 1);
550 policy = (SoupHSTSPolicy*)policies->data;
551 g_assert_cmpstr (policy->domain, ==, "freedesktop.org");
552 g_list_free_full (policies, (GDestroyNotify)soup_hsts_policy_free);
553 g_object_unref(enforcer);
554 }
555
556 int
main(int argc,char ** argv)557 main (int argc, char **argv)
558 {
559 int ret;
560 SoupServer *server;
561 SoupServer *https_server = NULL;
562
563 test_init (argc, argv, NULL);
564
565 server = soup_test_server_new (SOUP_TEST_SERVER_IN_THREAD);
566 soup_server_add_handler (server, NULL, server_callback, "http", NULL);
567 http_uri = soup_test_server_get_uri (server, "http", NULL);
568
569 if (tls_available) {
570 https_server = soup_test_server_new (SOUP_TEST_SERVER_IN_THREAD);
571 soup_server_add_handler (https_server, NULL, server_callback, "https", NULL);
572 https_uri = soup_test_server_get_uri (https_server, "https", NULL);
573 }
574
575 /* The case sensitivity test is run first because soup_message_headers_append()
576 interns the header name and further uses of the name use the interned version.
577 if we ran this test later, then the casing that this tests uses wouldn't be used. */
578 g_test_add_func ("/hsts/case-insensitive-header", do_hsts_case_insensitive_header_test);
579 g_test_add_func ("/hsts/basic", do_hsts_basic_test);
580 g_test_add_func ("/hsts/expire", do_hsts_expire_test);
581 g_test_add_func ("/hsts/delete", do_hsts_delete_test);
582 g_test_add_func ("/hsts/replace", do_hsts_replace_test);
583 g_test_add_func ("/hsts/update", do_hsts_update_test);
584 g_test_add_func ("/hsts/set_and_delete", do_hsts_set_and_delete_test);
585 g_test_add_func ("/hsts/no_hsts_header", do_hsts_no_hsts_header_test);
586 g_test_add_func ("/hsts/persistency", do_hsts_persistency_test);
587 g_test_add_func ("/hsts/subdomains", do_hsts_subdomains_test);
588 g_test_add_func ("/hsts/superdomain", do_hsts_superdomain_test);
589 g_test_add_func ("/hsts/multiple-headers", do_hsts_multiple_headers_test);
590 g_test_add_func ("/hsts/insecure-sts", do_hsts_insecure_sts_test);
591 g_test_add_func ("/hsts/missing-values", do_hsts_missing_values_test);
592 g_test_add_func ("/hsts/invalid-values", do_hsts_invalid_values_test);
593 g_test_add_func ("/hsts/extra-values", do_hsts_extra_values_test);
594 g_test_add_func ("/hsts/duplicated-directives", do_hsts_duplicated_directives_test);
595 g_test_add_func ("/hsts/case-insensitive-directives", do_hsts_case_insensitive_directives_test);
596 g_test_add_func ("/hsts/optional-quotations", do_hsts_optional_quotations_test);
597 g_test_add_func ("/hsts/ip-address", do_hsts_ip_address_test);
598 g_test_add_func ("/hsts/utf8-address", do_hsts_utf8_address_test);
599 g_test_add_func ("/hsts/session-policy", do_hsts_session_policy_test);
600 g_test_add_func ("/hsts/idna-addresses", do_hsts_idna_addresses_test);
601 g_test_add_func ("/hsts/get-domains", do_hsts_get_domains_test);
602 g_test_add_func ("/hsts/get-policies", do_hsts_get_policies_test);
603
604 ret = g_test_run ();
605
606 soup_uri_free (http_uri);
607 soup_test_server_quit_unref (server);
608
609 if (tls_available) {
610 soup_uri_free (https_uri);
611 soup_test_server_quit_unref (https_server);
612 }
613
614 test_cleanup ();
615 return ret;
616 }
617